我正在尝试解决decltype
会大大简化问题的问题,但我在decltype
使用*this
并添加const
时遇到问题限定符。下面的示例代码演示了这个问题。
#include <iostream>
struct Foo
{
void bar()
{
static_cast<const decltype(*this)&>(*this).bar();
}
void bar() const
{
std::cout << "bar" << std::endl;
}
};
int main(int argc, char* argv[])
{
Foo f;
f.bar(); // calls non-const method
return 0;
}
代码在MSVC2010中编译,但执行会递归,直到发生堆栈溢出。
Ideone报告编译器错误
prog.cpp: In member function 'void Foo::bar()':
prog.cpp:7:38: error: 'const' qualifiers cannot be applied to 'Foo&'
如果我改变了行
static_cast<const decltype(*this)&>(*this).bar();
到
static_cast<const Foo&>(*this).bar();
它按预期工作。
我是否滥用或误解了decltype?
答案 0 :(得分:14)
由于表达式*this
不是 id-expression (即它没有将实体命名为变量),因此decltype(*this)
给出了类型表达*this
。该类型为Foo&
,因此添加const
限定符并对其进行引用不会改变任何内容:要么以静默方式折叠为Foo&
(遵循参数折叠等规则),要么错误(const引用类型)。我不确定哪种行为是正确的,你实际上发现了两个行为不同的编译器。无论如何它并不重要,因为它不是你想要的。
您可以使用std::remove_reference<decltype(*this)>::type const&
代替,但这看起来有点难看。
如果您仍然感到困惑:
int* p;
// decltype(p) is the type of the variable p (or, the declared type)
// int*
// decltype( (p) ) is the type of the expression p
// int*& because p is an lvalue
// decltype(*p) is the type of the expression *p
// int& because *p is an lvalue