使用decltype将其强制转换为const

时间:2011-09-14 12:22:42

标签: c++ const c++11 decltype

我正在尝试解决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?

1 个答案:

答案 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