属性 binary_search 的编译错误
Compilation error for a binary_search on the attributes
我有一个向量 v
class 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. 构建 [= 的对象的时间35=] X
它有很多其他属性和 2。我需要编写一个极简主义的构造函数,我害怕我会在代码的其他地方错误地使用它。
我原以为 operator==
重载会使它起作用。为什么它不起作用?有没有一种解决方案不会强迫我用 attribute_1 = elem
创建 X
的实例?
Why does it not work?
std::binary_search
也使用比较对象来检查是否相等。这类似于 comp(a, b) || comp(b, a)
。如果该表达式为假,则 a 不小于 b,b 也不小于 a。因此它们必须相等。
由于这种用法,比较对象需要接受集合对象以及要搜索的值作为 第一个和第二个参数。
一种解决方案是使用 "projection" class,其对象既可以根据相关 class 构建,也可以根据您要比较的值构建。在第一种情况下,投影 class 然后从 class 成员中提取值并将其存储到它自己的成员中。在另一种情况下,它只是将值复制到它自己的成员。
有趣的是,这甚至可以变得非常笼统:
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) {}
};
这个投影class然后作为搜索使用的比较对象的两个参数。 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) {}
};
我有一个向量 v
class 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. 构建 [= 的对象的时间35=] X
它有很多其他属性和 2。我需要编写一个极简主义的构造函数,我害怕我会在代码的其他地方错误地使用它。
我原以为 operator==
重载会使它起作用。为什么它不起作用?有没有一种解决方案不会强迫我用 attribute_1 = elem
创建 X
的实例?
Why does it not work?
std::binary_search
也使用比较对象来检查是否相等。这类似于 comp(a, b) || comp(b, a)
。如果该表达式为假,则 a 不小于 b,b 也不小于 a。因此它们必须相等。
由于这种用法,比较对象需要接受集合对象以及要搜索的值作为 第一个和第二个参数。
一种解决方案是使用 "projection" class,其对象既可以根据相关 class 构建,也可以根据您要比较的值构建。在第一种情况下,投影 class 然后从 class 成员中提取值并将其存储到它自己的成员中。在另一种情况下,它只是将值复制到它自己的成员。
有趣的是,这甚至可以变得非常笼统:
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) {}
};
这个投影class然后作为搜索使用的比较对象的两个参数。 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) {}
};