我正在尝试使用std::tie
来实现operator<
,以便创建包含集合的结构图。没有模板的相同代码似乎有效。我从我的编译器获取此消息代码:
/ usr / include / c ++ / 4.8 / bits / stl_algobase.h:888:错误:
operator<
不匹配(操作数类型为const SiPa<int, int>
和const SiPa<int, int>
)if (*__first1 < *__first2) ^
如果我评论myMap.insert({akey, true});
行,则会编译所有内容。
任何提示?
template<class I = int, class S = int>
struct SiPa
{
I i;
S s;
};
template<class I = int, class S = int>
struct SiPaComparator
{
bool operator() (const SiPa<I, S>& first, const SiPa<I, S>& second) const
{
return std::tie(first.i, first.s) < std::tie(second.i, second.s);
}
};
template<class I = int, class S = int>
struct AKey
{
typedef std::set< SiPa<I, S>, SiPaComparator<I,S> > SetType;
SetType keySet;
I keyI;
};
template<class I = int, class S = int>
struct AKeyComparator
{
bool operator() (const AKey<I, S>& first, const AKey<I, S>& second) const
{
return std::tie(first.keySet, first.keyI) < std::tie(second.keySet, second.keyI);
}
};
int main()
{
AKey<int,int> akey;
std::map<AKey<int,int>, bool, AKeyComparator<int,int>> myMap;
myMap.insert({akey, true});
}
答案 0 :(得分:2)
您需要添加运算符&lt;对于struct SiPa,std :: map需要它
template<class I = int, class S = int>
struct SiPa {
I i;
S s;
bool operator<(const SiPa<I, S> &ref) {
return i < ref.i && s < ref.s;
}
};
答案 1 :(得分:2)
通常,map
和set
上的比较器有状态。在比较两个不同的set
或map
时,没有明显的方法可以选择使用哪个。
因此,在通过set
比较不同的map
和<
时,您会得到std::lexographical_compare
而没有Compare
参数,该参数使用<
。 (注意,对于不是来自同一数组的对象的set
指针,这很糟糕)
struct order_by_tie {
template<class Lhs, class Rhs,
class=std::enable_if_t<
std::is_base_of<order_by_tie, Lhs>::value
&& std::is_base_of<order_by_tie, Rhs>::value
>
>
friend bool operator<(Lhs const& lhs, Rhs const& rhs) {
return as_tie(lhs) < as_tie(rhs);
}
};
order_by_tie
旨在继承自。它使用ADL(参数依赖查找)在其后代类上启用<
,通过调用每一侧的自由函数as_tie
然后执行<
来实现。
我们按如下方式使用它:
template<class I = int, class S = int>
struct SiPa:order_by_tie
{
I i;
S s;
friend auto as_tie( SiPa const& self ) {
return std::tie(self.i, self.s);
}
};
template<class I = int, class S = int>
struct AKey:order_by_tie
{
typedef std::set< SiPa<I, S>, SiPaComparator<I,S> > SetType;
SetType keySet;
I keyI;
friend auto as_tie( AKey const& self ) {
return std::tie(self.keySet, self.keyI);
}
};
然后
std::map<AKey<int,int>, bool> myMap;
作品。
as_tie
使用C ++ 14,因为替代方案很烦人。您可以为C ++ 11添加-> decltype(std::tie( blah, blah ))
(重复自己)。
答案 2 :(得分:1)
根据http://www.cplusplus.com/reference/set/set/operators/
其他操作也使用运算符==和&lt;在内部比较元素,表现得好像执行了以下等效操作:
请注意,这些操作都不考虑两个容器的内部比较对象。
所以std::set<SiPa<I, S>, SiPaComparator<I,S>>
的比较完成了
operator < (const SiPa<I, S>&, const SiPa<I, S>&)
而不是
SiPaComparator<I, S>{}
解决方法是定义operator <
。