Nir*_*man 14 c++ templates vector c++11
一点概述.我正在编写一个提供强大typedef的类模板; 通过强类型定义我与一个只声明别名的常规typedef形成对比.提出一个想法:
using EmployeeId = StrongTypedef<int>;
Run Code Online (Sandbox Code Playgroud)
现在,强类型定义和隐式转换有不同的思想流派.其中一所学校说:并非每个整数都是EmployeeId,但每个EmployeeId都是一个整数,所以你应该允许从EmployeeId到整数的隐式转换.你可以实现这个,并编写如下内容:
EmployeeId x(4);
assert(x == 4);
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为x隐式转换为整数,然后使用整数相等比较.到现在为止还挺好.现在,我想用一个整数向量来做这个:
using EmployeeScores = StrongTypedef<std::vector<int>>;
Run Code Online (Sandbox Code Playgroud)
所以我可以这样做:
std::vector<int> v1{1,2};
EmployeeScores e(v1);
std::vector<int> v2(e); // implicit conversion
assert(v1 == v2);
Run Code Online (Sandbox Code Playgroud)
但我还是不能这样做:
assert(v1 == e);
Run Code Online (Sandbox Code Playgroud)
这不起作用的原因是因为如何std::vector定义其等式检查,基本上(模数标准):
template <class T, class A>
bool operator==(const vector<T,A> & v1, const vector<T,A> & v2) {
...
}
Run Code Online (Sandbox Code Playgroud)
这是一个功能模板; 因为它在早期的查找阶段被丢弃,所以不允许将隐式转换为vector的类型进行比较.
定义平等的另一种方式是这样的:
template <class T, class A = std::allocator<T>>
class vector {
... // body
friend bool operator==(const vector & v1, const vector & v2) {
...
}
} // end of class vector
Run Code Online (Sandbox Code Playgroud)
在第二种情况下,相等运算符不是函数模板,它只是与类一起生成的常规函数,类似于成员函数.这是由friend关键字启用的一个不寻常的案例.
问题(抱歉背景太长了),为什么不std::vector使用第二种形式而不是第一种形式呢?这使得vector行为更像原始类型,并且您可以清楚地看到它有助于我的用例.这种行为更令人惊讶,string因为很容易忘记它string只是类模板的typedef.
我考虑过两件事:首先,有些人可能认为因为友元函数是通过类生成的,如果向量的包含类型不支持相等比较,这将导致硬故障.不是这种情况; 与模板类的成员函数一样,如果未使用,则不会生成它们.其次,在更一般的情况下,自由函数的优点是它们不需要在与类相同的头中定义,这可以具有优势.但这显然没有在这里使用.
那么,是什么给出的?这有充分的理由,还是仅仅是次优选择?
编辑:我写了一个快速示例,演示了两件事:隐式转换按照朋友的方法工作,并且如果模板化类型不满足相等运算符的要求,则不会导致硬故障(显然,假设在这种情况下不使用相等运算符).编辑:改进与第一种方法形成鲜明对比:http://coliru.stacked-crooked.com/a/6f8910945f4ed346.
编辑:在我重新阅读我的解释并受到周围一些评论的影响后,我确信我最初的推理确实并不令人信服。我的回答本质上是试图论证,虽然一个值x可以隐式转换为y不同类型的值,但不一定期望两者之间进行“自动”相等比较。为了上下文化,我仍然保留我用作示例的代码。
struct B {};
template <class T>
struct A {
A() {}
A(B) {}
friend bool operator==(const A<T>&, const A<T>&) { return false; }
};
// The template version wouldn't allow this to happen.
// template <class T>
// bool operator==(const A<T>&, const A<T>&) { return false; }
int main() {
A<B> x;
B y;
if (x == y) {} //compiles fine
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
654 次 |
| 最近记录: |