在我的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;
}
我只是想明白,编译器是否坚持我在std :: result_of前加上&#34; typename&#34;因为它可能是不明确的,因为std :: result_of可以返回一个类,然后:: type可以是该类的成员?这就是为什么它坚持要添加typename?如果是这种情况,为什么Visual Studio允许它?它不合规吗?
另外,因为我已经读过从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
}
所以我知道lambda有一个删除的默认构造函数和复制赋值运算符,但是在这种情况下我真的认为在将lambda传递给这个模板化函数时会调用lambda的复制构造函数,它有它。然后当我做decltype(T())时我假设这将调用它的operator()函数。我不明白为什么它会说删除功能。
最后我尝试了:
decltype(std::declval<T()>) myVar = 5;
因为我认为declval可以用来创建你所做的任何电话的假实例,至少它是如何向我解释的。这也失败了,错误:
&#34;“main()::&amp;&amp;”类型的引用无效初始化 来自'int&#34;
类型的表达式
答案 0 :(得分:4)
<强>的result_of 强>
首先,GCC编译器在typename
之前需要关键字std::result_of
,因为后者的返回值是一个类。而且你必须指示它使用它的类型来声明一个新变量。
关于你的评论:
另外,因为我已经读过从C ++ 14或C ++ 17开始不推荐使用result_of
std::result_of
自C ++ 17(See here why)起不推荐使用,并被替换为
新引入的std::invoke_result
,如果你有一个兼容的编译器,你可以使用它。
<强> decltype 强>
由于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;
};
您可以使用类似的定义:
decltype( std::declval<T>()() ) myVar = 5;