命名空间std超载小于
namespace std overloading less than
我很好奇为什么这件代码不起作用:
#include "stdafx.h"
#include <iostream>
#include <tuple>
#include <string>
#include <vector>
#include <algorithm>
typedef std::tuple<int, std::string> intString;
bool operator<(intString& lhs, intString& rhs){
return std::tie(std::get<1>(lhs), std::get<0>(lhs)) < std::tie(std::get<1>(rhs), std::get<0>(rhs));
}
void printIntStrings(std::vector<intString>& v){
for (intString& i : v){
std::cout << std::get<0>(i) << " is " << std::get<1>(i) << std::endl;
}
}
int main(int argc, char* argv[])
{
std::vector<intString> v;
v.push_back(std::make_tuple(5, "five"));
v.push_back(std::make_tuple(2, "two"));
v.push_back(std::make_tuple(9, "nine"));
printIntStrings(v);
std::sort(v.begin(), v.end());
printIntStrings(v);
return 0;
}
据我所知,我只是创建一个intstrings的向量,而我的操作员应该先按元组中的第二个元素进行排序,因此输出应为(无论如何最后3行)
5 five
9 nine
2 two
但是在我的计算机上运行它
2 two
5 five
9 nine
这意味着该排序使用默认值小于运算符,而忽略了我指定的默认值。注意,在参数之前添加const似乎没有影响任何内容。
我找到了三种"修复"此方法的方法。
修复#1
环绕布尔操作员&lt;...在命名空间性标准中像这样:
namespace std{
bool operator<(intString& lhs, intString& rhs){
return std::tie(std::get<1>(lhs), std::get<0>(lhs)) < std::tie(std::get<1>(rhs), std::get<0>(rhs));
}
}
但是,我被告知我们永远不应该在性病名称空间中添加东西,因为该行为不确定,所以这个修复程序似乎是最糟糕的。
修复#2
在元组中添加一些自定义的东西:
enum class TRASH{DOESNTMATTER};
typedef std::tuple<int, std::string, TRASH> intString;
bool operator<(intString& lhs, intString& rhs){
return std::tie(std::get<1>(lhs), std::get<0>(lhs)) < std::tie(std::get<1>(rhs), std::get<0>(rhs));
}
(显然会添加垃圾:: desntmatter作为第三个make_tuple参数)但是,这似乎很简单,这似乎是很多工作。另外,由于没有有意义地使用枚举,这似乎很浪费。
修复#3
使用类似的谓词类似:
std::sort(v.begin(), v.end(), operator<);
这似乎是最优雅的解决方案。但是,我不明白为什么我必须明确告诉编译器使用我定义的操作员
。所以我想知道:
1)为什么会发生这种情况?C 不应该找到我的实现吗?
2)哪个"修复"是最好的?如果我找不到那些,您会推荐什么?
有什么想法吗?感谢您的阅读!
在使用<
的点上看不到您的operator<
过载(在std::sort
和/或IT所调用的任何辅助功能的正文中,<algorithm>
中的某个地方)。
如果要使用,则必须通过参数依赖性查找来挑选;但是std::tuple<int, std::string>
中没有任何包含全局名称空间作为关联名称空间的东西,因此ADL也不对您有帮助,并且使用了标准。
最简单的修复程序是将其作为比较器,最好使用lambda或函数对象(与函数指针更好)。我还建议将其重命名;具有与标准语义完全不同的语义的operator<
超载,该语义可以根据表达式在何处而被表达式a < b
使用,也不是一个好主意。
您已经通过自我修复了
问题是您的操作员&lt;函数不会覆盖默认元组::操作员,它们在不同的命名空间
所以,您的修复#1和Fix#3都是很好的解决方案
修复#1将它们放入相同的命名空间使其正确覆盖,我认为是最好的方法
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 从值小于256的uint16到uint8的Endian安全转换
- 将stl字符串缩小到小于15个字符的容量
- 如何检查两个 std::向量在小于 O(n) 的时间复杂度内是否相等
- 寻找地理和伤害意味着超载
- 为什么我只能在C++中使用可变长度数组分配小于 10 mb 的内存?
- 如何为字符串生成唯一但一致的 N 位哈希(小于 64 位)?
- 没有可行的超载'='用于shared_ptr
- "专业化不参与超载"
- sizeof(size_t) 可以小于 sizeof(int) 吗?
- C++:如何计算二叉树中其值模块高度小于 2 的节点数?
- unique_ptr < 0 或小于运算符做什么?
- 虚拟超载运算符>>和<<
- C++模板元编程(版本小于 17,最好是 11)
- 从小于或等于某个 N 的数字列表中最小化或找到 n 个理想的子集和
- 为什么我的超载"+"运算符返回的总额错误?
- c++curl返回413请求实体过大,但是post大小远小于max大小
- 如何在随机数列表中查找大于或小于的元素
- GetWindowRect()返回的大小小于游戏的实际可见窗口的可能原因是什么
- 命名空间std超载小于