В неконстантной функции-члене, почему точка это неконстантная, а указатель decltype это константа? - PullRequest
0 голосов
/ 31 мая 2019

У меня есть строго шаблонный класс, из которого я хочу использовать геттер. Следуя общепринятому соглашению, я избежал дублирования кода следующим образом:

template< typename Foo, typename... Bars >
class Templated
{
...

  constexpr const Foo& get() const 
  { 
    return mFoo;
  }

  constexpr Foo& get() 
  { 
    return const_cast<Foo&>(const_cast<const Templated<Foo, Bars...> *>(this)->get());
  }

Однако мне пришло в голову, что второе определение становится немного неуклюжим, особенно с классом, который имеет много параметров шаблона. К счастью, после небольшого возмущения я понял, что могу упростить это для любого универсального шаблона класса до:

constexpr Foo& get()
{
  return const_cast<Foo&>(const_cast<decltype(this)>(this)->get());

Это работает, потому что по какой-то причине decltype (this) преобразуется в константный указатель на тип объекта класса, тогда как just (this) преобразуется в неконстантный указатель на тип объекта класса. Почему в мире это так?

1 Ответ

1 голос
/ 31 мая 2019

«const указатель на тип объекта класса» не то, что вы хотите.

this является неизменным (this = nullptr; запрещено). Не *this.

Сделайте вашу жизнь намного проще, просто сделав add_const и remove_const шаблонные функции (или используйте std::as_const, если ваша версия C ++ достаточно новая):

template<typename T>
const T* add_const(T* ptr) { return ptr; } // no cast at all!

template<typename T>
T* remove_const(const T* ptr) { return const_cast<T*>(ptr); }
template<typename T>
T& remove_const(const T& ref) { return const_cast<T&>(ref); }

Здесь add_const(this) правильно приводит к `неконстантному указателю на тип константного объекта".


В этом отношении, внутри класса вы можете просто добавить

auto cthis() const { return this; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...