如何利用C++的deducing this特性实现rawdata()的单版本重载替代
利用C++ "推导this"特性简化
rawdata()的const/非const重载 我有一个用于处理图像的矩阵类,定义如下:
template<typename T> struct mat { size_t rows_, cols_; std::vector<T> data_; mat(size_t rows = 0, size_t cols = 0) : rows_(rows), cols_(cols), data_(rows* cols) {} size_t rows() const { return rows_; } size_t cols() const { return cols_; } size_t size() const { return data_.size(); } };
我已经通过C++的**"推导this"**特性实现了单个operator()方法,能根据对象的const性自动返回T&或const T&,比原来需要写两个重载版本简洁很多:
auto& operator()(this auto&& self, size_t r, size_t c) { return self.data_[r * self.cols_ + c]; }
现在我需要提供一个rawdata()方法,返回指向内部vector数据的[const] char*,供std::istream::read和std::ostream::write使用。目前的实现是两个重载版本:
char* rawdata() { return reinterpret_cast<char*>(data_.data()); } const char* rawdata() const { return reinterpret_cast<const char*>(data_.data()); } size_t rawsize() const { return data_.size() * sizeof(T); }
虽然可以用if constexpr实现单版本,但写法比直接复制粘贴更复杂。我想知道有没有更简便的实现方式,尤其是当函数体较长时,能根据对象的const性自动为返回类型添加const修饰,避免重复代码。
解决方案:用"推导this"实现单版本rawdata()
我们可以复用"推导this"的思路,写出一个能自动适配const/非const对象的rawdata()方法:
auto rawdata(this auto&& self) { using OrigPtr = decltype(self.data_.data()); using CharType = std::conditional_t<std::is_const_v<std::remove_pointer_t<OrigPtr>>, const char, char>; return reinterpret_cast<CharType*>(self.data_.data()); }
原理说明
- 通过
this auto&& self接收对象的万能引用,编译器会根据调用时对象的const性,自动推导self的类型(mat<T>&或const mat<T>&)。 - 借助
decltype获取data_.data()的原始指针类型(T*或const T*),再通过std::is_const_v判断指针指向的元素是否为const,对应生成char*或const char*类型。 - 这种方式只需要写一次函数体,后续无论函数逻辑如何扩展,都不需要维护两个重载版本。
如果想要更简洁的写法,还可以直接利用类型推导组合:
auto rawdata(this auto&& self) { return reinterpret_cast<std::add_pointer_t<std::conditional_t< std::is_const_v<std::remove_reference_t<decltype(self.data_)>>, const char, char >>>(self.data_.data()); }
内容的提问来源于stack exchange,提问作者Costantino Grana
相关产品推荐
相关产品推荐

