如何从自动返回类型推导出类型? [复制]

2024-03-28

这个答案 https://stackoverflow.com/a/11774533/476681有这样的代码片段:

template<class T, class F>
auto f(std::vector<T> v, F fun)
    -> decltype( bool( fun(v[0] ) ), void() )
{
  // ...
}

它确实可以编译并工作(至少在 Ideone 上 http://ideone.com/dhyxN).

那么,这种情况下类型是如何推导的呢?

c++11 标准真的允许下一行吗?

decltype( bool( fun(v[0] ) ), void() )

我快速浏览了一下,看起来不太有效。在这种情况下,ideone 错了吗?


c++11 标准中的所有示例都在 decltype 中只有一种类型:

struct A {
  char g();
  template<class T> auto f(T t) -> decltype(t + g())
  { return t + g(); }
};

另一个例子 :

void f3() {
  float x, &r = x;
  [=] {
  decltype(x) y1;
  decltype((x)) y2 = y1;
  decltype(r) r1 = y1;
  decltype((r)) r2 = y2;
};

和另一个

const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = i;
decltype(i) x2;
decltype(a->x) x3;
decltype((a->x)) x4 = x3;

它们在 decltype 中都只有一个参数。为什么上面的代码有两个参数(用逗号分隔)?


我创建了另一个示例(无法编译):

#include <vector>
#include <iostream>

template<class T, class F>
auto f(std::vector<T> v, F fun) -> decltype(bool(fun(v[0])), void())
{
  // ...
  (void)v;(void)fun;

  return fun(v.size());
}

void ops(int)
{
}

int main(){
  std::vector<int> v;
  f(v, [](int){ return true; });
  f(v,ops);
}

即使线f(v,ops);被删除时,返回类型f模板函数被评估为 void。


decltype( bool( fun(v[0] ) ), void() )使用逗号运算符 https://stackoverflow.com/questions/54142/c-comma-operator.

分解它,

bool( fun(v[0] ) ), void()

由两个表达式组成;首先

bool( fun(v[0] ) )

is evaluated1 and discarded, giving the overall expression the value

void()

which is a value2 of type void.

decltype然后产生表达式的类型,如上所示void.

这里使用逗号运算符的原因是为了确保只有第一个子表达式有效时整个表达式才有效;这是因为如果第一个子表达式无效,则在 SFINAE 中使用它来将其排除在替换考虑之外。

这是有效的,因为虽然decltype在语法上看起来像一个函数,它实际上是一个语言结构(比如sizeof) 被定义为采用单个参数。将逗号运算符参数放在括号中可能会更清楚:

decltype( ( bool( fun(v[0] ) ), void() ) )

Notes

  1. 表达方式bool( fun(v[0] ) ) is not actually评估,因为我们处于未评估的上下文 (decltype, 如同sizeof)。这里重要的是它would be如果对整个表达式进行求值,则求值,因此,如果子表达式无效,则整个表达式也无效。
  2. void() isn't really一个值,但它的行为类似于逗号运算符上下文中的值decltype.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从自动返回类型推导出类型? [复制] 的相关文章

随机推荐