【问题标题】:Using decltype to cast this to const使用 decltype 将其强制转换为 const
【发布时间】:2011-09-14 12:22:41
【问题描述】:

我正在尝试解决decltype 将大大简化事情的问题,但我在*this 上使用decltype 并添加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?

【问题讨论】:

  • const_cast 可能会更好地表达意图。
  • @Cubbi 向谁表达意图?
  • @Jesse :我认为他的意思是 const_cast&lt;Foo const*&gt;(this)-&gt;bar(); 在这种情况下比任何涉及 decltype 的东西都更容易阅读
  • @ildjam 我的意思是建议使用 const_cast 来表明所有复杂的表达式所做的只是改变 constness,但looks like I was wrong
  • @Potatoswatter - 你抓住了我。 ;) 我确实在预处理器宏中使用decltype 为涉及 const 正确性的某个习语“生成”一些代码。我意识到预处理器并不是理想的代码生成工具。

标签: c++ constants c++11 decltype


【解决方案1】:

由于表达式*this 不是id-表达式(即它不命名实体,如变量),那么decltype(*this) 给出表达式*this 的类型.该类型是Foo&amp;,因此添加const 限定符并对其进行引用不会改变任何内容:要么它默默地折叠到Foo&amp;(遵循引用折叠等规则),要么它是一个错误(一个常量引用类型)。我不确定哪种行为是正确的,实际上您已经找到了两个行为不同的编译器。在任何情况下都没有关系,因为这不是你想要的。

您可以改用std::remove_reference&lt;decltype(*this)&gt;::type const&amp;,但这看起来有点难看。

如果您仍然感到困惑:

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

【讨论】:

  • std::remove_reference 适合我。感谢您的建议!
猜你喜欢
  • 1970-01-01
  • 2013-10-20
  • 2019-02-04
  • 2011-01-20
  • 2016-09-24
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
  • 2015-01-17
相关资源
最近更新 更多