【问题标题】:initialize a set with a comparison structure that depends on "this" c++使用依赖于“this”c++的比较结构初始化一个集合
【发布时间】:2014-03-02 18:27:42
【问题描述】:

我想定义一个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()
       ^

总结问题:

  • 似乎我无法在声明中使用比较来初始化集合,因为它依赖于 this
  • set 声明后的比较函数初始化失败,不知道为什么。

解决方案感谢@WhozCraig 将 mySet 声明为:

std::set<ContentType, doCompare> mySet;

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

mySet(doCompare(*this))

【问题讨论】:

  • 可能普遍缺乏const 的正确性。
  • 我用编译器错误更新了问题。该错误似乎与doCompare 定义中的consts 无关。我认为更基本的东西是错误的......
  • 问题是,他想在构造函数的初始化列表中使用this。另见:stackoverflow.com/questions/869281/…
  • @Siamak 也许我不明白你的回答,或者你不明白我的问题。 std::set 接受作为第二个模板参数的 type 用于比较(不是函数;虽然你可以使用函数类型,但你不是)。没有指定类型 std::less&lt;T&gt; 是默认值。您在构造函数中传递的比较器object(它不是一个函数,它是一个functor)与std::less&lt;T&gt; 不匹配,也不匹配任何其他std::set&lt;ContentType&gt;备用构造函数参数列表。因此你的错误“没有匹配的功能”。 See it live
  • 再次查看发布的现场样本。回头看看我的第一条评论。该decl应该是std::set&lt;ContentType,doCompare&gt;,注意第二个参数。没有this 涉及(还没有;稍后在MyClass 构造函数初始化列表中)。不相关(稍微),我相信您很有可能也应该将 doCompare::_mc 引用成员设为 const。我认为没有理由让它变热。

标签: c++ stl initialization set


【解决方案1】:

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

std::set<ContentType> mySet;

展开时的意思:

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

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

mySet 的声明更改为:

std::set<ContentType,doCompare> mySet;

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多