【问题标题】:Why member variables of a const object are not const为什么 const 对象的成员变量不是 const
【发布时间】:2016-06-30 20:54:09
【问题描述】:

刚刚问了一个类似的问题,归结为这个问题。

#include <iostream>
using namespace std;

struct A {
    A() : a{1} {};
    int a;
};

template <typename Which>
struct WhichType;

int main() {
    const A a;
    const A& a_ref = a;
    const A* a_ptr = &a;
    WhichType<decltype(a.a)> which_obj; // template evaluates to int
    WhichType<decltype(a_ref.a)> which_ref; // template evaluates to int
    WhichType<decltype(a_ptr->a)> which_ptr; // template evaluates to int

    return 0;
}

为什么模板没有变成const int 而不是int

【问题讨论】:

    标签: c++ reference constants c++14 decltype


    【解决方案1】:

    decltype 为您提供操作数的“声明类型”,如果它没有包含在一组额外的括号中。

    要获取表达式的实际类型,即const int,您必须编写decltype((a.a)) 等等。

    decltype 始终为除名称之外的左值表达式返回引用类型。

    【讨论】:

    • 所以decltype always 只返回代码中定义的名称声明的类型?忽略所有被带到那里的对象的constness、refness 或volatileness?例如const 对象中的变量?
    • @Curious 对于操作数只是变量名称或成员访问表达式的特定情况,是的,它给出了声明的类型。封闭对象的 cv 限定修改了表达式的类型,但如果您使用额外的括号,您只能获得表达式的类型。类似的事情也适用于价值类别。
    【解决方案2】:

    当传递一个标识符(或成员)的名称时,它返回声明的类型。

    当传递一个不同的表达式时,它会返回更接近你想要的东西,但有引用限定。

    WhichType<std::remove_reference_t<decltype((a_ptr->a))>> which_ptr; // template evaluates to const int!
    

    live example 或者如果你想要 l/r 价值:

    WhichType<decltype((a_ptr->a))> which_ptr2; // template evaluates to const int&
    WhichType<decltype(((const A){}.a))> which_ptr3; // template evaluates to const int
    

    您可以在此处附加 &amp;&amp; 以使其成为“真正的”右值引用。

    WhichType<decltype(((A){}.a))&&> which_ptr4; // template evaluates to int&&!
    

    live example.

    【讨论】:

    • 太好了!我在 Scott Meyer 的 C++ 书中看到了这种方法,所以在使用时我什至没有考虑它。关于decltype,除了这个微妙之处,我还有什么需要知道的吗?
    • 你可以用std::declval&lt;const A&gt;()代替(const A){}
    • @jarrod 当然,但这更长!
    • 如果A 不是默认可构造的,(const A){} 将失败,我认为它的可读性较差。
    • 上次我检查时,(const A){} 是 C99 复合文字,而不是标准 C++。此外,prvalue 上的类成员访问应该产生一个 xvalue(对于非引用、非静态数据成员),尽管显然您的编译器还没有实现该 DR。
    猜你喜欢
    • 2020-04-15
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多