c++ - 运算符<在 std::pair 上重新定义在课堂模板中
问题描述
我在类模板案例中遇到以下情况:
template<class T1,class T2>
class targetClass{
public:
typedef typename std::pair<T1, T2> ToSortType;
typedef typename std::set<ToSortType> ContainerSort;
void bar(ToSortType a, ToSortType b);
private:
ContainerSort container;
bool operator<(const ToSortType& rhs) const;
}
template<class T1,class T2>
void targetClass<T1,T2>::bar(ToSortType a, ToSortType b){
container.insert(a);
container.insert(b);
}
template <class T1,class T2>
bool targetClass<T1,T2>::operator<(const ToSortType& rhs) const
{
return this->first < rhs.first;
}
在主函数中是这样的:
targetClass<int,T2> anObjectTarget;
T2 a;
T2 b;
anObjectTarget.bar(std::make_pair(0,a),std::make_pair(1,b));
T2
通常没有定义的operator<
用户定义类型在哪里?在这种情况下,编译器无法为. 在前面的代码片段中,我重新定义了相关的运算符,但编译器以这种方式抱怨:std::set
std::pair<int,T2>
operator<
int
T2
T2
/usr/include/c++/7/bits/stl_pair.h:456: error: no match for ‘operator<’ (operand types are ‘const T2’ and ‘const T2’)
|| (!(__y.first < __x.first) && __x.second < __y.second); }
~~~~~~~~~~~^~~~~~~~~~~~
我以前从未重新定义过运算符,但查看文档对我来说是正确的(但不是编译器)。
解决方案
您重载的运算符是其中的一个成员,targetClass<T1,T2>
并将两个ToSortType
作为参数。这不是<
运算符重载的工作方式。考虑到对于类类型的实例,以下两个是等价的:
a < b
a.operator<(b)
即运算符只是调用特殊成员函数的语法糖。您编写的运算符只能称为
targetClass<T1,T2> t;
T1 a;
T2 b;
t.operator<(a,b);
但是该集合试图调用的是a < b
,即a.operator(b)
显然不存在(std::pair<T1,T2>
只能通过<
when both T1
and T2
can)。
长话短说:您不能使用运算符来比较ToSortType
.
我不建议尝试重载operator<
for std::pair<T1,T2>
,而是使用自定义类型:
template<class T1,class T2>
class targetClass{
public:
struct value_type {
T1 first;
T2 second;
bool operator<(const value_type& other) {
return first < rhs.first;
}
}
using container_type = std::set<value_type>;
void bar(const value_type& a,const value_type& b);
private:
container_type container;
};
如果您想留下来,那么您可以使用允许您选择比较器类型的std::pair
事实。std::set
但是,首先我必须解释一下以免使您感到困惑,因为以下内容似乎与上述内容相矛盾(事实并非如此)。set 使用的默认比较器是std::less<Key>
,这是一个类型,operator()
它比较两个类型的元素Key
,它类似于(但不完全是)这样的:
template <typename Key>
struct less {
bool operator() (const Key& a,const Key& b) const {
return a < b;
}
};
这是编译器无法<
为您的Key
类型(即std::pair<T1,T2>
)找到 a 的地方。您可以使用自己的比较器:
template <typename T1,typename T2>
struct my_comparator {
bool operator() (const std::pair<T1,T2>& a, const std::pair<T1,T2>& b) const {
return a.first < b.first;
}
};
然后你的设置是
using container_type = std::set<typename std::pair<T1,T2>,typename my_comparator<T1,T2>>;
推荐阅读
- snowflake-cloud-data-platform - 可以将 snowsql 配置为运行 login.sql 脚本而不退出吗?
- c# - Dynamics crm 查询表达式“联系人”不包含属性
- java - 旋转显示时Recyclerview丢失数据,按下按钮Android时加载数据
- ruby - 为什么我需要挽救异常?
- git - 在分支中进行一些文件更改后无法切换到另一个分支的情况是什么?
- proof - 使用图灵约简证明语言是不可判定的
- unity3d - Unity2D:看对象正在翻转我的对象
- sqlite - FireDAC SQLite 标准加密问题
- python - 如何访问 django 模板中的图像?
- javascript - SyntaxError:JSON 中位置 0 处的意外标记 p 在提取中