【问题标题】:Compilation error for a binary_search on the attributes属性上的 binary_search 编译错误
【发布时间】:2017-03-05 05:17:53
【问题描述】:

我有一个 v 类实例的向量 X

class X
{
public:
  int attribute_1;
  ... 

  operator==(const int i){return this->attribute_1 == i;}
};

std::vector<X> v;

向量v按属性attribute_1排序。我想执行binary_search 来测试给定整数是否与X 实例之一的attribute_1 匹配。我试过了

int elem = 12
bool isElementPresent = std::binary_search(
        v.begin(),
        v.end(),
        elem,
        [](const X& right, const X& left){return right.attribute_1 < left.attribute_1;}
      )
    )

但是编译失败。如果我创建一个X 的实例并将attribute_1 设置为elem,那么它可以工作,但我想避免这样做(因为1. 时间构建类X 的对象有很多其他属性和 2. 我需要编写一个极简构造函数,并且害怕我会在代码的其他地方错误地使用它)。

我原以为operator== 重载会使其工作。为什么它不起作用?有没有不强制我用attribute_1 = elem 创建X 实例的解决方案?

【问题讨论】:

  • 你不能使用 lambda。您需要一个具有两个重载operator() 的类,一个采用X 和int ,另一个采用int 和X。您需要能够在两个方向上将elem 与实际向量元素进行比较。或者,构造一个X 的实例,将attribute_1 设置为elem,并将其传递给std::binary_search
  • 不清楚为什么您期望operator== 会有所作为。谁应该使用它,以及如何使用它?期望它如何提供帮助?反正std::binary_search实际上并没有使用它。

标签: c++ compiler-errors compilation find binary-search


【解决方案1】:

为什么它不起作用?

std::binary_search 也使用比较对象来检查是否相等。这与comp(a, b) || comp(b, a) 类似。如果该表达式为假,则 a 不小于 b,b 也不小于 a。因此它们必须相等。

由于这种用法,比较对象需要接受集合的对象以及要搜索的值作为两个第一个和第二个参数。

一种解决方案是使用“投影”类,其对象既可以从相关类构造,也可以从您要比较的值构造。在第一种情况下,投影类然后从类成员中提取值并将其存储到自己的成员中。在另一种情况下,它只是将值复制到它自己的成员。

很有趣,这甚至可以说得非常笼统:

template<typename D, typename P, P> struct projection;

template<typename Data, typename Class, typename Return, Return (Class::*member_function) () const>
struct projection<Data, Return (Class::*) () const, member_function> {
 Data data;
 projection (Class const & object)
  : data ((object.*member_function)()) {}
/* template<typename X>
 projection (X&& input)
  : data (std::forward<X>(input)) {}*/
 projection (Data d) : data (d) {}
};

然后将此投影类用作搜索使用的比较对象的两个参数。 Example:

struct Item {
 int x;
 int get () const { return x; }
};


int main () {
 Item items [] = {1,2,3,4,5,99};
 using P = projection<int, decltype(&Item::get), &Item::get>;
 auto compare = [](P const & left, P const & right) {
               return left.data < right.data; };
 std::cout << std::binary_search(
      std:: begin (items), std::end(items),
      4, compare)
    << std::endl;
 std::cout << std::binary_search(
      std:: begin (items), std::end(items),
      44, compare)
    << std::endl;
}

上面的代码使用了常量成员函数(“getters”),但它具有以下特化also works with pointers to members:

template<typename Data, typename Class, typename Member, Member (Class::*member_pointer)>
struct projection<Data, Member (Class::*), member_pointer> {
 Data data;
 projection (Class const & object)
  : data (object.*member_pointer) {}
/* template<typename X>
 projection (X&& input)
  : data (std::forward<X>(input)) {}*/
 projection (Data d) : data (d) {}
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多