【发布时间】:2017-10-03 10:06:38
【问题描述】:
在我的 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 前面加上“typename”,因为它可能不明确,因为 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 可以用作创建任何调用的假实例,至少我是这样解释的。这也失败并出现错误:
"'main()::&&' 类型的引用初始化无效 来自“int”类型的表达式
【问题讨论】:
-
您问题前半部分的高度相关/重复:stackoverflow.com/questions/610245/…
-
而且模板的 MSVC 实现多年来一直不兼容。 Only now did they implement it.
-
使用
T(),您不是在调用闭包的调用运算符,而是在声明一个返回该 lambda 的函数。另外,你真的应该每个问题问一个问题。
标签: c++ c++11 templates generics decltype