我不了解std :: result_of和decltype的这些用法 [英] I'm not understanding these uses of std::result_of and decltype
问题描述
在我的Visual Studio项目中,我有以下内容,并且运行良好:
On my Visual Studio project I had the following and it worked fine:
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;
}
我只是想了解一下,是编译器坚持要求我为std作序: :result_of具有类型名,因为它可能是含糊的,在该std :: result_of中可以返回一个类,然后:: type可以成为该类的成员吗?这就是为什么它坚持要添加类型名称吗?如果是这种情况,那么为什么Visual Studio允许它?还不合规吗?
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?
此外,由于我已经阅读到自C ++ 14或C ++ 17起不推荐使用result_of,因此我想尝试并使用更通用的decltype,应该在更多情况下使用。所以我尝试了:
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:
template <typename T>
void function(T type)
{
decltype(T()) myVar = 5; // Error, use of deleted function‘main()::<lambda()>::<lambda>()’ main.cpp
}
所以我知道lambda具有已删除的默认构造函数和复制赋值运算符,但是在这种情况下,我确实认为将lambda传递给此模板时函数lambda的副本构造函数被调用,它确实具有。然后,当我执行decltype(T())时,我假设这将调用其operator()函数。我不明白为什么它会说一些有关删除功能的信息。
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.
最后我尝试了:
decltype(std::declval<T()>) myVar = 5;
因为我认为declval可以像在调用时创建假实例一样使用至少那是对我的解释。这也会因错误而失败:
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:
类型为'main()::&&'
的引用的无效初始化从类型'int'
"invalid initialization of reference of type ‘main()::&&’ from expression of type ‘int"
推荐答案
result_of
首先,GCC编译器在 std :: result_of $ c之前要求关键字
typename
$ c>,因为后者的返回值是一个类。并且必须指示它使用其类型来声明新变量。
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.
关于您的评论:
另外,因为我已经阅读到自C ++ 14或C ++ 17起不推荐使用result_of
Also, because I've read that result_of is being deprecated as of C++14 or C++17
从C ++ 17开始不推荐使用
std :: result_of
(在这里查看原因),并用新引入的 std :: invoke_result
替换为
,所以您如果您有兼容的编译器,则可以改用它。
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.
decltype
std :: result_of
是按照 decltype
的以下方式声明的:
Since std::result_of
is declared in terms of decltype
in the following manner:
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;
这篇关于我不了解std :: result_of和decltype的这些用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!