简体   繁体   中英

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. 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.

Ideone reports compiler error

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?

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 . 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). 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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