On my Visual Studio project I had the following and it worked fine:
在我的Visual Studio项目中,我有以下内容,它工作正常:
template <typename T>
void function(T type)
{
std::result_of<T()>::type myVar = 5; // This compiled fine with Visual Studio,
but with GCC it shows the following errors:
//error: dependent-name ‘std::result_of<T()>::type’ is parsed as a non-type,
//but instantiation yields a type. note: say ‘typename std::result_of<T()>::type’ if a type is meant
}
int main() {
auto lambda = []() { return float(); };
function(lambda);
return 0;
}
I just want to understand, is the compiler insisting that I preface the std::result_of with "typename" because it could be ambiguous, in that std::result_of could return a class, and then ::type could be a member of that class? Is that why it's insisting that typename be added? If this is the case then why does Visual Studio allow it? Is it non compliant?
我只是想理解,编译器是否坚持我在std :: result_of前加上“typename”,因为它可能是不明确的,因为std :: result_of可以返回一个类,然后:: type可以是一个类的成员类?这就是为什么它坚持要添加typename?如果是这种情况,为什么Visual Studio允许它?它不合规吗?
Also, because I've read that result_of is being deprecated as of C++14 or C++17, I wanted to try and use the more generic decltype, which is supposed to work in more circumstances. So I tried:
另外,因为我已经读过从C ++ 14或C ++ 17开始不推荐使用result_of,我想尝试使用更通用的decltype,它应该适用于更多情况。所以我尝试过:
template <typename T>
void function(T type)
{
decltype(T()) myVar = 5; // Error, use of deleted function‘main()::<lambda()>::<lambda>()’ main.cpp
}
So I'm aware that a lambda has a deleted default constructor and copy assignment operator, but in this case I really think that when passing the lambda to this templated function the lambda's copy constructor is called, which it does have. Then when I do decltype(T()) I assume this would be calling its operator() function. I don't understand why it says something about deleted function.
所以我知道lambda有一个删除的默认构造函数和复制赋值运算符,但在这种情况下我真的认为在将lambda传递给这个模板化函数时,会调用lambda的复制构造函数,它具有它。然后当我做decltype(T())时我假设这将调用它的operator()函数。我不明白为什么它说删除功能的东西。
And finally I tried with:
最后我尝试了:
decltype(std::declval<T()>) myVar = 5;
Because I thought that declval can be used as if creating a fake instance of whatever call you make, at least that's how it was explained to me. This also fails with error:
因为我认为declval可以用来创建你所做的任何调用的虚假实例,至少就是它向我解释的方式。这也失败了,错误:
"invalid initialization of reference of type ‘main()::&&’ from expression of type ‘int"
“从类型'int”的表达式初始化'main():: &&'类型的引用无效
1 个解决方案
#1
4
result_of
First, the GCC compiler requires the keyword typename
before std::result_of
because the return value of the latter is a class. And you have to instruct it to use its type to declare a new variable.
首先,GCC编译器在std :: result_of之前需要关键字typename,因为后者的返回值是一个类。而且你必须指示它使用它的类型来声明一个新变量。
Regarding your comment:
关于你的评论:
Also, because I've read that result_of is being deprecated as of C++14 or C++17
另外,因为我已经读过从C ++ 14或C ++ 17开始不推荐使用result_of
std::result_of
is deprecated as of C++17 (See here why) and is replaced by the newly introduced std::invoke_result
, so you could use it instead if you have a compliant compiler.
从C ++ 17开始,不推荐使用std :: result_of(请参见此处原因)并由新引入的std :: invoke_result替换,因此如果您有兼容的编译器,则可以使用它。
decltype
Since std::result_of
is declared in terms of decltype
in the following manner:
由于std :: result_of以decltype的形式以下列方式声明:
template<typename _Signature>
struct result_of;
template<typename _Functor, typename... _ArgTypes>
struct result_of<F(Args...)> {
typedef decltype( std::declval<F>()(std::declval<Args>()...) ) type;
};
You could use a similar definition:
您可以使用类似的定义:
decltype( std::declval<T>()() ) myVar = 5;
#1
4
result_of
First, the GCC compiler requires the keyword typename
before std::result_of
because the return value of the latter is a class. And you have to instruct it to use its type to declare a new variable.
首先,GCC编译器在std :: result_of之前需要关键字typename,因为后者的返回值是一个类。而且你必须指示它使用它的类型来声明一个新变量。
Regarding your comment:
关于你的评论:
Also, because I've read that result_of is being deprecated as of C++14 or C++17
另外,因为我已经读过从C ++ 14或C ++ 17开始不推荐使用result_of
std::result_of
is deprecated as of C++17 (See here why) and is replaced by the newly introduced std::invoke_result
, so you could use it instead if you have a compliant compiler.
从C ++ 17开始,不推荐使用std :: result_of(请参见此处原因)并由新引入的std :: invoke_result替换,因此如果您有兼容的编译器,则可以使用它。
decltype
Since std::result_of
is declared in terms of decltype
in the following manner:
由于std :: result_of以decltype的形式以下列方式声明:
template<typename _Signature>
struct result_of;
template<typename _Functor, typename... _ArgTypes>
struct result_of<F(Args...)> {
typedef decltype( std::declval<F>()(std::declval<Args>()...) ) type;
};
You could use a similar definition:
您可以使用类似的定义:
decltype( std::declval<T>()() ) myVar = 5;