如何消除返回std::span的const与非const函数间的代码重复?
避免const/非const成员函数代码重复的方案
对于你这种同时提供std::span返回值的const和非const成员函数的场景,有两种简洁的方式避免代码重复,以下是最常用的实现:
方法1:非const版本复用const版本逻辑(推荐)
核心思路是让非const的myFunc()调用const版本的实现,再通过const_cast安全去除返回值的const限定——因为当前对象本身是非const的,这种转换不会触发未定义行为。
修改后的代码如下:
class Foo { public: std::span<int> myFunc() { // 先将当前对象转为const类型,调用const版本方法 auto const_span = static_cast<const Foo*>(this)->myFunc(); // 转换span的元素const属性 return const_cast<std::span<int>>(const_span); } std::span<const int> myFunc() const { auto begin{vec.begin()}; auto end{vec.end()}; // Do some work that modifies begin and end. return {begin, end}; } private: std::vector<int> vec{1, 2, 3}; };
方法2:提取核心逻辑到私有模板函数
把修改begin和end的通用逻辑抽成私有模板函数,让两个版本的myFunc()各自传入对应迭代器类型调用模板。
示例代码:
class Foo { public: std::span<int> myFunc() { auto [begin, end] = getBounds(vec.begin(), vec.end()); return {begin, end}; } std::span<const int> myFunc() const { auto [begin, end] = getBounds(vec.cbegin(), vec.cend()); return {begin, end}; } private: std::vector<int> vec{1, 2, 3}; // 模板函数封装核心逻辑,适配任意迭代器类型 template<typename Iterator> std::pair<Iterator, Iterator> getBounds(Iterator begin, Iterator end) const { // Do some work that modifies begin and end. return {begin, end}; } };
第一种方法更简洁,是处理const/非const重载的标准做法;第二种方法逻辑分离更清晰,适合核心逻辑复杂、需要适配多种迭代器的场景。
内容的提问来源于stack exchange,提问作者Archduke
相关产品推荐
相关产品推荐

