首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么用'add_rvalue_reference<T>::type‘而不是'T&&’来指定'declval‘?

为什么用'add_rvalue_reference<T>::type‘而不是'T&&’来指定'declval‘?
EN

Stack Overflow用户
提问于 2012-01-22 01:30:54
回答 3查看 1.3K关注 0票数 20

§20.2.4 [declval]

template <class T>
typename add_rvalue_reference<T>::type declval() noexcept; // as unevaluated operand

为什么要在这里使用add_rvalue_reference

来自add_rvalue_reference上的§20.9.7.2 [meta.trans.ref]

如果T命名对象或函数类型,则成员

type应命名为T&&;否则,type应命名为T。注意:此规则反映了引用折叠(8.3.2)的语义。例如,当类型T将类型命名为T1&时,类型add_rvalue_reference<T>::type不是右值引用。-end笔记

既然add_rvalue_reference旨在以任何方式反映引用折叠,为什么不像下面这样使用T&&呢?

template<class T>
T&& declval();

会出什么问题呢?这两个版本到底有什么不同?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-22 01:48:08

我不知道这是否是真正的原因,但是add_rvalue_referencevoid有不同的行为。

add_rvalue_reference<void>::type就是简单的void

void&&是一个错误。

票数 17
EN

Stack Overflow用户

发布于 2012-01-22 01:53:19

有几个定义依赖于declval为cv合格的void提供合理的结果。is_assignable就是一个例子

template <class T, class U>
struct is_assignable;

当将表达式declval<T>() = declval<U>()视为未计算的操作数时,该表达式的格式是正确的...

其意图是“良构的”指的是赋值表达式的良构,而不是declval<T>本身是否良构。也就是说,我们一次只需要担心一件事。

票数 11
EN

Stack Overflow用户

发布于 2012-01-22 01:54:44

不同之处在于,只有当T是对象类型或函数类型时,add_rvalue_reference<>才真正添加&&部件。如果T不是对象或函数类型(例如void),您就不想添加&&

参见this example on Ideone

This webpage of Boost's implementation解释说:

函数模板declval()的作用是在不使用或计算此函数的情况下将类型T转换为值。这个名字应该引导读者注意这样一个事实:当且仅当T是左值引用时,表达式declval<T>()才是左值,否则是右值。为了扩展这个函数的域,我们可以做得更好一些,将它的声明改为

模板类型名称std::add_rvalue_reference::type declval();//不使用

这确保了我们还可以使用cv void作为模板参数。

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

https://stackoverflow.com/questions/8955052

复制
相关文章

相似问题

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