【问题标题】:I'm not understanding these uses of std::result_of and decltype我不理解 std::result_of 和 decltype 的这些用途
【发布时间】: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”类型的表达式

【问题讨论】:

标签: c++ c++11 templates generics decltype


【解决方案1】:

result_of

首先,GCC编译器要求typenamestd::result_of之前,因为后者的返回值是一个类。而且你必须指示它使用它的类型来声明一个新变量。

关于您的评论:

另外,因为我已经读到 result_of 从 C++14 或 C++17 开始被弃用

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;

【讨论】:

  • 不是很好;有一些微妙的极端情况会导致结果错误。这就是它被弃用的原因。
  • @Yakk,我不知道这种极端情况。在我寻找有关此事的正式参考资料时,我删除了我对此事的评论。你能指点我相关的信息吗?
  • 如果 decltype 和 declval 可以做同样的事情,为什么要把 result_of 替换为 invoke_result 呢?还是不能?
  • @DanielTrugman 有个问题 :) stackoverflow.com/questions/46021734/…
  • @Zebrafish,您可以在 C++ 中以多种方式做很多事情,但您希望语言尽可能简单。
猜你喜欢
  • 2011-02-10
  • 2014-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多