简体   繁体   English

使用decltype将其强制转换为const

[英]Using decltype to cast this to const

I'm attempting to solve a problem in which decltype will greatly simplify things, but I'm running into an issue using decltype on *this and adding a const qualifier. 我试图解决一个问题,其中decltype将大大简化事情,但我遇到问题使用decltype on *this并添加一个const限定符。 The sample code below demonstrates the problem. 下面的示例代码演示了该问题。

#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;
}

The code compiles in MSVC2010, but execution recurses until a stack overflow occurs. 代码在MSVC2010中编译,但执行会递归,直到发生堆栈溢出。

Ideone reports compiler error Ideone报告编译器错误

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

If I change the line 如果我换行

static_cast<const decltype(*this)&>(*this).bar();

to

static_cast<const Foo&>(*this).bar();

it works as expected. 它按预期工作。

Am I misusing or misunderstanding decltype? 我是否滥用或误解了decltype?

Since the expression *this is not an id-expression (ie it doesn't name an entity, like a variable), then decltype(*this) gives the type of the expression *this . 由于表达式*this不是id表达式 (即它没有命名实体,如变量),因此decltype(*this)给出表达式*this的类型。 That type is Foo& , so adding a const qualifier and making a reference to that doesn't change anything: either it silently collapse to Foo& (following rules like reference collapsing), or it's an error (a const reference type). 那个类型是Foo& ,所以添加一个const限定符并对其进行引用不会改变任何东西:要么静默地折叠到Foo& (遵循规则,如引用折叠),要么它是一个错误(一个const引用类型)。 I'm not sure which behaviour is correct, and you have in fact found two compilers which behave differently. 我不确定哪种行为是正确的,你实际上发现了两个行为不同的编译器。 In any case it doesn't matter because it's not what you want. 无论如何它并不重要,因为它不是你想要的。

You can use std::remove_reference<decltype(*this)>::type const& instead but that looks a bit ugly. 您可以使用std::remove_reference<decltype(*this)>::type const&而不是看起来有点难看。

In case you're still confused: 如果你仍然困惑:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM