gpt4 book ai didi

c++ - 如何从自动返回类型推导出类型?

转载 作者:可可西里 更新时间:2023-11-01 17:08:10 25 4
gpt4 key购买 nike

This answer有这样的代码片段:

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

它确实可以编译并工作(at least on Ideone)。

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

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() ) 使用 comma operator .

分解,

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

由两个表达式组成;第一个

bool( fun(v[0] ) )

被评估1并被丢弃,为整个表达式赋予值

void()

它是 void 类型的值2

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

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

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

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

注意事项

  1. 表达式 bool( fun(v[0] ) ) 实际上 未计算,因为我们处于非计算上下文(decltype,类似于sizeof)。这里重要的是,如果对整个表达式求值,它将被求值,因此如果子表达式无效,则整个表达式无效。
  2. void() 不是真正的值,但它在逗号运算符和 decltype 的上下文中表现得像一个值。

关于c++ - 如何从自动返回类型推导出类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11775639/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com