使用decltype将其强制转换为const

Jes*_*son 11 c++ const decltype c++11

我试图解决一个decltype会大大简化问题的问题,但是我遇到了一个使用decltypeon *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;
}
Run Code Online (Sandbox Code Playgroud)

代码在MSVC2010中编译,但执行会递归,直到发生堆栈溢出.

Ideone报告编译器错误

prog.cpp: In member function 'void Foo::bar()':
prog.cpp:7:38: error: 'const' qualifiers cannot be applied to 'Foo&'
Run Code Online (Sandbox Code Playgroud)

如果我换行

static_cast<const decltype(*this)&>(*this).bar();
Run Code Online (Sandbox Code Playgroud)

static_cast<const Foo&>(*this).bar();
Run Code Online (Sandbox Code Playgroud)

它按预期工作.

我是否滥用或误解了decltype?

Luc*_*ton 14

由于表达式*this不是id表达式(即它不命名实体,如变量),因此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
Run Code Online (Sandbox Code Playgroud)

  • `std :: remove_reference`对我很有用.感谢您的建议! (2认同)