c++ - 是否有原因 declval 返回 add_rvalue_reference 而不是 add_lvalue_reference

标签 c++ c++11

将类型更改为类型的reference,允许访问该类型的成员而无需创建该类型的实例。 lvalue referencesrvalue references 似乎都是如此。

declval 是用 add_rvalue_reference 而不是 add_lvalue_reference 实现的,

  • 这只是一个约定吗,
  • 或者有没有使用 add_rvalue_reference 更可取的例子?

编辑: 我想我有点含糊,这些答案都很好,但触及的点略有不同。建议使用两种不同的答案,Howard 强调您可以选择您的类型所具有的引用,从而使 add_rvalue_reference 更加灵活。其他答案强调默认行为会自动选择更自然地反射(reflect)输入类型的引用。不知道选什么!如果有人可以添加两个简单的示例,分别激发对每个属性的需求,那么我会很满意。

最佳答案

add_rvalue_reference :

  • declval<Foo>()Foo&& 类型.
  • declval<Foo&>()Foo& 类型(引用折叠:“Foo& &&”折叠为 Foo&)。
  • declval<Foo&&>()Foo&& 类型(引用折叠:“Foo&& &&”折叠为 Foo&&)。

add_lvalue_reference :

  • declval<Foo>()将是 Foo& 类型.
  • declval<Foo&>()将是 Foo& 类型(引用折叠:“Foo& &”折叠为 Foo&)。
  • declval<Foo&&>()将是 Foo& 类型(!)(引用折叠:“Foo&& &”折叠为 Foo&)。

也就是说,你永远不会得到 Foo&& .

另外,declval<Foo>()Foo&& 类型很好(你可以写 Foo&& rr = Foo(); 但不能写 Foo& lr = Foo(); )。 还有 declval<Foo<b>&&</b>>()将是 Foo<b>&</b> 类型只是觉得“不对劲”!


编辑:既然你问了一个例子:

#include <utility>
using namespace std;

struct A {};
struct B {};
struct C {};

class Foo {
public:
    Foo(int) { } // (not default-constructible)

    A onLvalue()   &  { return A{}; }
    B onRvalue()   && { return B{}; }
    C onWhatever()    { return C{}; }
};

decltype( declval<Foo& >().onLvalue()   ) a;
decltype( declval<Foo&&>().onRvalue()   ) b;
decltype( declval<Foo  >().onWhatever() ) c;

如果 declval使用 add_lvalue_reference你不能使用 onRvalue()用它(第二个 decltype )。

关于c++ - 是否有原因 declval 返回 add_rvalue_reference 而不是 add_lvalue_reference,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20303250/

相关文章:

c++ - 私有(private)子句中的变量与 OpenMP 中并行区域中定义的变量之间有什么区别吗?

c++ - 如何分隔 C++ 字符串中的数字和字母?

c++ - 如何将 lambda 的 operator() 声明为 noreturn?

c++ - 将字符串转换为数字以便更快地比较它们

c++ - 将人类可读的日期转换为毫秒并在不丢失信息的情况下再次返回

C++ 错误 : deduced conflicting types for parameter 'T' string vs const char *

c++ - GPU 加速排序 (~1GB) 和归并排序 (~100GB)

c++ - QTimer 根本不准确?

c++ - 安全获取 &std 列表项?

c++ - Qt 'Rectangle' 不是类型 - 当矩形被声明为类时