我有一个模板化很强的类,我想从中使用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_const
和remove_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; }