c++ - 特化模板类并添加新接口
问题描述
我有一个通用模板类Vector
。预期用途是让用户专门化泛型Vector
并定义任何自定义操作。例如,
using IntVector = Vector<int>;
IntVector operator+ (const IntVector& a, const IntVector& b);
问题是有些操作不能定义为自由函数,比如IntVector& operator+= (const IntVector& b);
. 要解决这个问题,您可以通过继承进行专业化,
class IntVector : public Vector<int> {
public:
IntVector& operator+= (const IntVector& b);
};
IntVector operator+ (const IntVector& a, const IntVector& b);
但是,这有一个问题,在基本模板类上定义的切片运算符返回一个泛型Vector_view
而不是IntVector_view
支持operator+=
. 您将不得不使用与基类相同的主体重载切片运算符,只是返回类型不同,这是令人讨厌的。
这是一个相关的问题,建议制作一个包装器对象,这对于每种具体类型来说都相当乏味。有没有什么简单的方法可以创建一个专业化,您可以在其中添加新接口而无需重新定义类型?如果这是唯一的答案,我认为创建通用基类没有意义。
解决方案
你不需要做任何特别的事情+=
。
如果我误解了这个问题,请纠正我。可以定义诸如operator+=
自由函数之类的东西。例如,以下是您定义它的方式std::vector
:
#include <vector>
std::vector<int>& operator+=(std::vector<int>& a, std::vector<int> const& b) {
if(b.size() != a.size())
throw std::logic_error("SIN! SIN! SIN!");
auto* b_scan = b.data();
for(int& value : a) {
value += *b_scan++;
}
return a;
}
或者,如果您想避免污染全局命名空间,您可以在与您的Vector
类相同的命名空间中定义它,并且由于 Argument-Dependent Lookup,它仍然可以正常工作。
其他运营商呢,比如operator[]
?
不幸的是,类似的东西必须是成员函数operator[]
。我们可以允许用户通过创建一个调用用户提供的函数的通用模板来定义它的行为:
class Vector {
// Stuff
public:
value_t& operator[] (int idx);
const value_t& operator[] (int idx) const;
// Add this
auto operator[](T index) -> decltype(get_index(*this, index)) {
return get_index(*this, index);
}
};
用户可以operator[]
通过定义来控制get_index
. 例如,我们可以为get_index
for Vector<int>
like 提供一个定义:
Vector_view<int> get_index(Vector<int>& v, std::pair<int, int> p) {
return {v.begin() + p.first, v.begin() + p.second};
}
这个定义可以跟在的定义之后Vector
,不一定要前向声明,因为operator[]
是模板,编译器还是会找到的。您可以在此处查看一个工作示例。
推荐阅读
- audio - 在特定的应用程序文件夹中下载音频并在应用程序中再次访问它......如何?
- vega - Vega 不按降序排序
- javascript - 可访问性和 Javascript:加载动态内容或显示和隐藏?
- powershell - 为什么每次迭代后我的 foreach 变量都不会在 PowerShell 中输出?
- javascript - 如何与 Selenium JS 中的本地存储进行交互?
- r - 从数据集中提取数据并将其格式化为R中的矩阵
- amazon-web-services - 是否有一个所有 docker 容器都有的 URL 会返回 200?
- razor - 需要从实体中获取 2sxc 字段类型
- google-cloud-firestore - 从 BigQuery 将数据写入 Firestore 的快速方法
- c++ - c++ 使用引用作为数组/指针是否合法?