在非常量成员函数中,为什么点这个非常量,而 decltype 指针这是常量



我有一个模板化很强的类,我想从中使用getter。按照一个共同的约定,我避免了代码重复,如下所示:

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( 解析为指向类对象类型的 const 指针,而 (this( 解析为指向类对象类型的非 const 指针。为什么会这样呢?

"指向

类对象类型的常量指针"不是你想要的。

this是不可变的(this = nullptr;是非法的(。 不*this.

只需制作add_constremove_const模板函数(或者如果您的C++版本足够新,请使用std::as_const,让您的生活轻松:

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

最新更新