【问题标题】:Why does this work? std::set find with search key and custom comparator为什么这行得通? std::set 使用搜索键和自定义比较器查找
【发布时间】:2012-02-28 15:00:46
【问题描述】:

我不明白为什么以下方法有效(尽管我很高兴它有效!):

我可以使用自定义比较器定义对象的std::set。这个自定义比较器通过比较被比较的两个对象的一些成员变量来工作。 但是然后我可以使用set.find(x) 函数,其中x 是成员变量类型而不是对象本身,它可以工作!

这是一个极其简化的例子:

my_class.h

class my_class   //just hold an integer
{
    public:
      int an_int;

    my_class(int new_int) : an_int(new_int)
    { }


    //compare instances of this class by comparing their integers...
    struct compare_instances   
    {    
      bool operator() (const my_class &a, const my_class &b) const
      {
        return a.an_int < b.an_int;
      }
    };
};

main.cpp:

...
std::set<my_class, my_class::compare_instances> my_class_set;
my_class_set.insert( my_class(18) );
my_class_set.insert( my_class(7)  );
my_class_set.insert( my_class(22) );

std::set<my_class, my_class::compare_instances>::const_iterator found_it
                  = my_class_set.find(18);
 std::fprintf(stderr, "found_it->an_int = %d\n", found_it->an_int); 

输出:“found_it->an_int = 18”!!!!!!

我原以为上面的代码不能编译,编译器会冲我大喊“18 不是my_class”类型。但它没有......

.find 的参数不应该与set 本身的元素类型相同吗?这就是文档似乎所说的......

【问题讨论】:

  • 看看你的构造函数:my_class(int new_int)。您可以从int 开始创建my_class。尝试find("blah"),它不会编译:)

标签: c++ stl find set compare


【解决方案1】:

这是有效的,因为int 可以隐式转换为您的类。任何未标记为explicit 并且可以仅使用一个不属于类本身类型的参数调用的构造函数都定义了隐式转换。实际上,这意味着,每当需要一个类类型的对象时,您也可以使用int,它会自动转换。

【讨论】:

  • 好的,您已将我的所有观点添加到您的答案中。我正在删除我的其他 cmets。 8v)
  • @FredLarson 即使可能不相关,您会建议始终声明显式构造函数吗?
  • @vulkanino:如果您不想要隐式转换,这可能不是一个坏主意。我不知道将explicit 添加到构造函数有任何问题,即使它不能用于隐式转换。
  • 哇哇哇,太好了,多么微妙的细节。你认为这是一种好的做法吗?它确实让事情变得简单 - 我可以通过整数搜索 set 的对象(感谢隐式构造函数)。但是当然,隐式构造函数会构建整个 Object 来进行搜索……这是一种浪费。有一个更好的方法吗?在一组中搜索我的对象?我可以使用map,其中的关键是would-be-member-variable-for-comarator...但这会增加一定程度的复杂性。
  • @CycoMatto: This question 处理这个问题。
猜你喜欢
  • 2021-10-23
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-09
  • 1970-01-01
  • 2014-04-14
相关资源
最近更新 更多