为什么std :: declval添加引用?

Pot*_*ter 43 c++ decltype c++11

std::declval是一个编译时实用程序,用于构造表达式以确定其类型.它的定义如下:

template< class T >
typename std::add_rvalue_reference<T>::type declval() noexcept;
Run Code Online (Sandbox Code Playgroud)

这不会更简单吗?

template< class T >
T declval() noexcept;
Run Code Online (Sandbox Code Playgroud)

参考返回类型的优点是什么?不应该被称为declref

我找到的最早的历史例子是n2958,它调用函数value()但总是返回一个引用.

注意,操作数decltype不需要具有可访问的析构函数,即它没有在语义上被检查为完整表达式.

template< typename t >
t declprval() noexcept;

class c { ~ c (); };
decltype ( declprval< c >() ) * p = nullptr; // OK
Run Code Online (Sandbox Code Playgroud)

T.C*_*.C. 37

decltype只有当函数调用本身是decltype逗号运算符的操作数或右操作数时,"规则中的对象类型的函数返回prvalue才会引入临时性"(仅适用于decltype(§5.2.2[expr.call])/p11),这意味着declprvalOP 中给出的,

template< typename t >
t declprval() noexcept;

class c { ~ c (); };

int f(c &&);

decltype(f(declprval<c>())) i;  // error: inaccessible destructor
Run Code Online (Sandbox Code Playgroud)

不编译.更一般地说,返回T会阻止大多数不declval完整类型的非平凡用法,使用私有析构函数键入等等:

class D;

int f(D &&);

decltype(f(declprval<D>())) i2;  // doesn't compile. D must be a complete type
Run Code Online (Sandbox Code Playgroud)

这样做几乎没有什么好处,因为xvalues与prvalues几乎无法区分,除非你使用decltype它们,并且你通常不decltype直接使用返回值declval- 你已经知道了类型.


650*_*502 12

数组不能通过值返回,因此即使只是声明按值返回数组的函数也是无效代码.

但是,您可以通过引用返回一个数组.

  • @Jamboree:使用`typedef int A [4]`将使`A f();`无效代码. (2认同)