当前位置:  开发笔记 > 编程语言 > 正文

为什么将std :: vector和std :: string的比较运算符定义为模板函数?

如何解决《为什么将std::vector和std::string的比较运算符定义为模板函数?》经验,为你挑选了0个好方法。

一点概述.我正在编写一个提供强大typedef的类模板; 通过强类型定义我与一个只声明别名的常规typedef形成对比.提出一个想法:

using EmployeeId = StrongTypedef;

现在,强类型定义和隐式转换有不同的思想流派.其中一所学校说:并非每个整数都是EmployeeId,但每个EmployeeId都是一个整数,所以你应该允许从EmployeeId到整数的隐式转换.你可以实现这个,并编写如下内容:

EmployeeId x(4);
assert(x == 4);

这是有效的,因为x隐式转换为整数,然后使用整数相等比较.到现在为止还挺好.现在,我想用一个整数向量来做这个:

using EmployeeScores = StrongTypedef>;

所以我可以这样做:

std::vector v1{1,2};
EmployeeScores e(v1);
std::vector v2(e); // implicit conversion
assert(v1 == v2);

但我还是不能这样做:

assert(v1 == e);

这不起作用的原因是因为如何std::vector定义其等式检查,基本上(模数标准):

template 
bool operator==(const vector & v1, const vector & v2) {
...
}

这是一个功能模板; 因为它在早期的查找阶段被丢弃,所以不允许将隐式转换为vector的类型进行比较.

定义平等的另一种方式是这样的:

template >
class vector {
... // body

  friend bool operator==(const vector & v1, const vector & v2) {
  ...
}

} // end of class vector

在第二种情况下,相等运算符不是函数模板,它只是与类一起生成的常规函数​​,类似于成员函数.这是由friend关键字启用的一个不寻常的案例.

问题(抱歉背景太长了),为什么不std::vector使用第二种形式而不是第一种形式呢?这使得vector行为更像原始类型,并且您可以清楚地看到它有助于我的用例.这种行为更令人惊讶,string因为很容易忘记它string只是类模板的typedef.

我考虑过两件事:首先,有些人可能认为因为友元函数是通过类生成的,如果向量的包含类型不支持相等比较,这将导致硬故障.不是这种情况; 与模板类的成员函数一样,如果未使用,则不会生成它们.其次,在更一般的情况下,自由函数的优点是它们不需要在与类相同的头中定义,这可以具有优势.但这显然没有在这里使用.

那么,是什么给出的?这有充分的理由,还是仅仅是次优选择?

编辑:我写了一个快速示例,演示了两件事:隐式转换按照朋友的方法工作,并且如果模板化类型不满足相等运算符的要求,则不会导致硬故障(显然,假设在这种情况下不使用相等运算符).编辑:改进与第一种方法形成鲜明对比:http://coliru.stacked-crooked.com/a/6f8910945f4ed346.

推荐阅读
个性2402852463
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有