【问题标题】:What does -> after a function prototype mean?-> 在函数原型之后是什么意思?
【发布时间】:2013-05-26 18:15:36
【问题描述】:

这段代码发生了什么?太混乱了。

#include <utility>

struct check
{
   template <typename T>
   auto foo() -> decltype(std::declval<T>().value, void())
   {
      static_assert(T{}.value == 10, "Incorrect value");
   }
} var;

int main()
{
   struct apple
   {
      int value{10};
   };

   var.foo<apple>();
}

特别是它具有-&gt; 的部分以及之后的所有内容。

【问题讨论】:

  • -> 是尾随返回类型。 declval 创建一个类的实例。 decltype 查找编译时表达式的类型。 static_assert 是一个编译时断言。是时候把它们拼凑起来了:)
  • 模糊的标题对其他有同样问题的人没有用处。
  • @RiaD:虽然标题编辑更有帮助,但仍然不准确 - 他似乎在询问特定用途。
  • 对标题进行了编辑,提示“函数原型之后的 -> 是什么意思?”。

标签: c++ c++11


【解决方案1】:

让我们一点一点来。

auto foo() -> decltype(std::declval<T>().value, void())

这是一个尾随返回类型。允许使用参数,但在这里不是必须的。我想它是这样写的更清楚。 decltype 找到内部表达式的类型,但实际上并未计算该表达式。 std::declval 用于创建传递给它的类型的实例。逗号运算符在这里用于生成整体返回类型void,因为逗号运算符计算左侧,将其丢弃,计算右侧,然后返回。

第一部分创建了一种 SFINAE(尽管我从未见过这样使用它)。例如,如果您有一个 foo 的重载,它对 value2 而不是 value 执行相同的操作,那么调用哪个就不会有歧义。我的意思见here。将其与 this one 进行比较,后者的返回类型为 void 并导致错误。

static_assert(T{}.value == 10, "Incorrect value");

此行确保 T 的值初始化实例的 value 成员的值为 10。如果不是,则会生成带有该文本的编译器错误。

} var;

这只是要使用的该类的全局对象。

struct apple
{
   int value{10};
};

这是一个用于测试它的示例类。它有一个 value 成员,并且该成员在值初始化实例中为 10(也是默认初始化)。

var.foo<apple>();

这只是调用函数。

【讨论】:

  • 当我执行struct grape {}; var.foo&lt;grape&gt;(); 时,它给了我一个错误。我怎样才能让它静默失败?
  • @MemyselfandI,你需要有一个foo 的版本,它适用于葡萄等结构。问题是你必须确保用apple 调用它不是模棱两可的。我会试着准备一个例子。
  • @MemyselfandI,非常感谢 Xeo,here you go。您可以根据该类型是否具有value 数据成员来实现foo
猜你喜欢
  • 1970-01-01
  • 2020-01-01
  • 2017-02-08
  • 2020-12-04
  • 2013-01-25
  • 2012-12-07
  • 1970-01-01
  • 2019-08-15
  • 1970-01-01
相关资源
最近更新 更多