使用依赖于 "this" C++ 的比较结构初始化集合

initialize a set with a comparison structure that depends on "this" c++

本文关键字:结构 比较 初始化 集合 C++ 依赖于 this      更新时间:2023-10-16

我想定义一个set,它根据当前类的其他成员的值进行比较:

std::set<ContentType> mySet(doComparison(*this));

其中doCompare是一个结构体:

struct doCompare{
   doCompare(  MyClass& mc ) : _mc(mc) { }
   MyClass& _mc;
   bool operator()( const ContentType & i1, const ContentType & i2  ){ 
         return _mc.otherMember[i1] < _mc.otherMemeber[i2];
   }
};

这里的mySetMyClass的成员,当我尝试使用初始化列表中的比较函数初始化集合时:mySet(doCompare(*this))代码无法编译。

我在这里做错了什么?

错误是:

no matching function for call to ``std::set<ContentType>::set(MyClass::doCompare)`

以下是完整的消息(更改了名称以提高可读性):

./myclass.h:74:165: error: no matching function for call to ‘std::set<ContentType>::set(MyClass::doCompare)’
 :  mySet(doCompare(*this)) {
                                                                                                ^
./myclass.h:74:165: note: candidates are:
In file included from /usr/include/c++/4.8/set:61:0,
                 from ./myclass.h:12,
                 from [blah blah]
/usr/include/c++/4.8/bits/stl_set.h:193:7: note: std::set<_Key, _Compare, _Alloc>::set(const std::set<_Key, _Compare, _Alloc>&) [with _Key = ContentType; _Compare = std::less<ContentType >; _Alloc = std::allocator<ContentType >]
       set(const set& __x)
       ^
/usr/include/c++/4.8/bits/stl_set.h:193:7: note:   no known conversion for argument 1 from ‘MyClass::doCompare’ to ‘const std::set<ContentType >&’
/usr/include/c++/4.8/bits/stl_set.h:180:2: note: template<class _InputIterator> std::set<_Key, _Compare, _Alloc>::set(_InputIterator, _InputIterator, const _Compare&, const allocator_type&)
  set(_InputIterator __first, _InputIterator __last,
  ^
/usr/include/c++/4.8/bits/stl_set.h:180:2: note:   template argument deduction/substitution failed:
In file included from [blahblah]:
./myclass.h:74:165: note:   candidate expects 4 arguments, 1 provided
 :  mySet(doCompare(*this)) {
                                                                                                ^
In file included from /usr/include/c++/4.8/set:61:0,
                 from ./myclass.h:12,
/usr/include/c++/4.8/bits/stl_set.h:163:2: note: template<class _InputIterator> std::set<_Key, _Compare, _Alloc>::set(_InputIterator, _InputIterator)
  set(_InputIterator __first, _InputIterator __last)
  ^
/usr/include/c++/4.8/bits/stl_set.h:163:2: note:   template argument deduction/substitution failed:
In file included from [blahblah]:
./myclass.h:74:165: note:   candidate expects 2 arguments, 1 provided
 : mySet(doCompare(*this)) {
                                                                                                ^
In file included from /usr/include/c++/4.8/set:61:0,
                 from ./myclass.h:12,
                 from blahblah:
/usr/include/c++/4.8/bits/stl_set.h:148:7: note: std::set<_Key, _Compare, _Alloc>::set(const _Compare&, const allocator_type&) [with _Key = ContentType; _Compare = std::less<ContentType >; _Alloc = std::allocator<ContentType >; std::set<_Key, _Compare, _Alloc>::allocator_type = std::allocator<ContentType >]
       set(const _Compare& __comp,
       ^
/usr/include/c++/4.8/bits/stl_set.h:148:7: note:   no known conversion for argument 1 from ‘MyClass::doCompare’ to ‘const std::less<ContentType >&’
/usr/include/c++/4.8/bits/stl_set.h:139:7: note: std::set<_Key, _Compare, _Alloc>::set() [with _Key = ContentType; _Compare = std::less<ContentType>; _Alloc = std::allocator<ContentType >]
       set()
       ^

总结一下问题:

  • 似乎我无法通过声明中的比较初始化集合,因为它取决于
  • 声明集合后使用比较函数初始化失败,但我不知道为什么。

解决方案得益于@WhozCraig将 mySet 声明为:

std::set<ContentType, doCompare> mySet;

并在初始化列表中将其初始化为:

mySet(doCompare(*this))

您没有使用正确的模板比较器参数声明设置类型。这:

std::set<ContentType> mySet;

扩展时表示:

std::set<ContentType, std::less<ContentType>> mySet

为简洁起见,省略了分配器。这意味着在构造mySet并指定备用比较器函子时,它必须是 std::less<ContentType> 型,但您的不是。它属于doCompare型。编译器尝试与所有其他构造函数参数列表匹配,但找不到任何匹配项,最终导致错误。

将您的mySet声明更改为:

std::set<ContentType,doCompare> mySet;

现在,类型应该正确连接。

正如我在评论中所说,我认为没有理由在您的比较对象中保留对您的MyClass的引用应该是非常量。 除非你能想到一个很好的理由,否则我建议将引用更改为 const,即 const MyClass&