const方法中decltype的结果

Ola*_*del 2 c++ typeof decltype c++11

C++ 11 decltype返回给出的表达式的类型(主要是).但这可能与表达式的类型不同,因为它实际上是可访问的:

template<typename T>
struct Ref {
    Ref(T&) { }
};

#define GETTYPE decltype
//#define GETTYPE typeof

struct Problem {
    void doit_c() const { Ref<GETTYPE(n)> rn{n}; }
    void doit_nc()      { Ref<GETTYPE(n)> rn{n}; }
    int n;
};

int main() {
    int i;
    const int ci = 0;
    Problem pr;

    // decltype == typeof == int
    Ref<GETTYPE(i)> ri{i};
    pr.doit_nc();

    // decltype == typeof == const int
    Ref<GETTYPE(ci)> rci{ci};
    Ref<GETTYPE(static_cast<const int&>(i))> rcci{static_cast<const int&>(i)};

    // typeof == const int, decltype == int (!)
    pr.doit_c();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在该示例中,Ref如果T与实际构造函数参数不匹配,则结构仅用于导致编译错误.该Problem::doit_c()方法decltype(n)返回非const结果,即使n在此上下文中为const.

如果从标准切换decltype到GNU扩展typeof,这似乎考虑了方法的常量.

现在我的问题:是否有符合C++ 11/C++ 14/C++ 17的替代decltype()/ typeof()对于表达式(如上面没有编译错误),如上面const-method中的声明?

编辑:

  • 简化第一句删除一些错误并停止分散注意力的问题(谢谢,@ skypjack)

  • 简化了示例代码中宏的使用(谢谢,@ Richard Critten)

AnT*_*AnT 6

decltype是一个有点坐在两把椅子上的功能.首先,顾名思义,它可以为您提供实体的确切声明类型,忽略使用它的上下文.其次,它可以将其参数视为一个表达式,其确切类型取决于上下文及其值类别.

decltype直接应用于"裸"(unsarenthesized)类成员访问是一种特殊情况,其中decltype按照其第一个角色行事.它不会被n视为一种表达.相反,它将生成该类成员的类型,忽略上下文.

如果您希望将其n视为表达式,则必须将其括起来

struct Problem {
  void doit_c() const 
  { 
    Ref<decltype(n)> rn1{n}; // `decltype(n)` is `int` -> ERROR
    Ref<decltype((n))> rn2{n}; // `decltype((n))` is `const int &` -> compiles OK
  }
};
Run Code Online (Sandbox Code Playgroud)