首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么std::declval添加引用?

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

Stack Overflow用户
提问于 2014-09-07 05:44:57
回答 3查看 5K关注 0票数 49

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

代码语言:javascript
复制
template< class T >
typename std::add_rvalue_reference<T>::type declval() noexcept;

难道这不是更简单吗?

代码语言:javascript
复制
template< class T >
T declval() noexcept;

引用返回类型的优点是什么?不是应该叫declref吗?

我找到的最早的历史示例是n2958,它调用函数value(),但始终返回引用。

注意,decltype的操作数不需要有一个可访问的析构函数,也就是说,它没有作为一个完整表达式进行语义检查。

代码语言:javascript
复制
template< typename t >
t declprval() noexcept;

class c { ~ c (); };
decltype ( declprval< c >() ) * p = nullptr; // OK
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-09-07 06:30:26

只有当函数调用本身是decltype的操作数或作为decltype操作数的逗号运算符的右操作数(§5.2.2 expr.call/p11),这意味着在OP中给定declprval时,才适用“在decltype中为返回对象类型的值的函数引入非临时的”规则。

代码语言:javascript
复制
template< typename t >
t declprval() noexcept;

class c { ~ c (); };

int f(c &&);

decltype(f(declprval<c>())) i;  // error: inaccessible destructor

不编译。更普遍地说,返回T将防止大多数不完全类型的declval的重要使用,使用私有析构函数的类型,等等:

代码语言:javascript
复制
class D;

int f(D &&);

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

这样做没有什么好处,因为xvalue与prvalue几乎没有区别,除非在它们上使用decltype,而且通常不会在declval的返回值上直接使用decltype --您已经知道了类型。

票数 44
EN

Stack Overflow用户

发布于 2014-09-07 06:07:55

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

但是,可以通过引用返回数组。

票数 12
EN

Stack Overflow用户

发布于 2014-09-07 06:26:59

decltype()的目的是让表达式充当T类型的有效值,在期望Ts的表达式中充当T,问题是在C++中,类型T可以是不可复制的,甚至是不可默认的。因此,为此目的使用T{}是行不通的。

decltype()所做的是返回对T的rvalue引用。rvalue引用对于任何类型的T都应该是有效的,因此它保证我们有来自T的rvalue引用的有效T,并且它的保证可以有对任何类型T的rvalue引用。这就是诀窍。

decltype()想成“给我一个有效的T类型的表达式”。当然,它的用途是用于重载解析、类型确定等;因为它的目的是返回一个有效表达式(在语法意义上),而不是返回一个值。这反映在std::declval()根本没有定义,它只声明了一个事实。

如果定义了它,我们将再次遇到初始问题(我们必须为任意类型的T构造一个值,这是不可能的)。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25707441

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档