【发布时间】:2017-07-03 14:08:42
【问题描述】:
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;
}
在示例中,Ref 结构仅用于在 T 与实际构造函数参数不匹配时导致编译错误。 Problem::doit_c() 方法是 decltype(n) 返回非 const 结果的地方,即使 n 在此上下文中是 const。
如果从标准 decltype 切换到 GNU 扩展 typeof,这似乎考虑了该方法的 const-ness。
现在我的问题:对于表达式,是否有符合 C++11 / C++14 / C++17 的替代 decltype() / typeof() 表现“正确”(如:上面没有编译错误)像上面的 const-method 中的声明?
已编辑:
简化了第一句话以消除一些错误并停止分散问题的注意力(感谢@skypjack)
简化了示例代码中宏的使用(感谢@Richard Critten)
【问题讨论】:
-
C++11
decltype在声明类型时返回给它的表达式的类型。这不准确。decltype有很多规则与你的说法或多或少有所不同。 -
请不要在示例问题中使用宏(除非问题与宏有关)。
-
“即使
n在这种情况下是 const。” 不,不是。this指针指向const对象。在const对象中声明的成员int n仍然是int,而不是const int。在我看来,decltype()的判断是正确的,而不是typeof()的判断。 -
完全没有想到,我猜你可以在
*this上使用is_const,如果那是true,那么add_const是会员的类型。跨度> -
"在
const对象中声明的成员int n仍然是int,而不是const int。"我同意该类型的成员变量是非常量的。但是Problem::doit_c()中的左值n是const,编译器抱怨就证明了这一点。