如何使 find() 能够处理一组结构?
我正在使用 set
来保存包含多个字符串的结构。我希望能够使用集合的 find()
功能。但是,由于该集合保存结构,因此它不起作用。我希望 find() 只查看结构中的字符串之一。这怎么能做到呢?
这是我尝试使用的代码。除了使用 find()
的部分之外,它工作正常:
#include <iostream>
#include <string>
#include <set>
using namespace std;
struct test
{
string key;
string data;
};
bool operator<(const test & l, const test & r)
{
return l.key < r.key;
}
bool operator==(const test & l, const test & r)
{
return l.key == r.key;
}
set<test> s;
int main()
{
test newmember;
newmember.key = "key";
newmember.data = "data";
s.insert(newmember);
s.find("key");
}
以下是我尝试编译它时收到的错误消息:
test.cpp:30:7: error: no matching member function for call to 'find'
s.find("key");
~~^~~~
In file included from test.cpp:3:
In file included from /usr/include/c++/4.2.1/set:65:
/usr/include/c++/4.2.1/bits/stl_set.h:429:7: note: candidate function not viable: no known conversion from 'const char [4]' to 'const key_type' (aka 'const test') for 1st argument
find(const key_type& __x)
^
/usr/include/c++/4.2.1/bits/stl_set.h:433:7: note: candidate function not viable: no known conversion from 'const char [4]' to 'const key_type' (aka 'const test') for 1st argument
find(const key_type& __x) const
^
1 error generated.
I am using a set
to hold structs which contain several strings. I want to be able to use the find()
functionality of sets. However, since the set is holding structs, it doesn't work. I want find()
to look only at one of the strings in the struct. How can this be done?
Here's the code that I tried to use. It works fine except for the part where find()
is used:
#include <iostream>
#include <string>
#include <set>
using namespace std;
struct test
{
string key;
string data;
};
bool operator<(const test & l, const test & r)
{
return l.key < r.key;
}
bool operator==(const test & l, const test & r)
{
return l.key == r.key;
}
set<test> s;
int main()
{
test newmember;
newmember.key = "key";
newmember.data = "data";
s.insert(newmember);
s.find("key");
}
Here are the error messages that I get when I try to compile it:
test.cpp:30:7: error: no matching member function for call to 'find'
s.find("key");
~~^~~~
In file included from test.cpp:3:
In file included from /usr/include/c++/4.2.1/set:65:
/usr/include/c++/4.2.1/bits/stl_set.h:429:7: note: candidate function not viable: no known conversion from 'const char [4]' to 'const key_type' (aka 'const test') for 1st argument
find(const key_type& __x)
^
/usr/include/c++/4.2.1/bits/stl_set.h:433:7: note: candidate function not viable: no known conversion from 'const char [4]' to 'const key_type' (aka 'const test') for 1st argument
find(const key_type& __x) const
^
1 error generated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我建议您将
operator<
和operator==
添加到您的结构中,而不是重载全局运算符,我发现它更干净;示例:现在讨论您真正的问题 - 您将一个字符串传递给
find()
函数,但它只接受test
类型的结构。为此,请添加一个用于自动转换的构造函数,因此最终的结构将如下所示:然后将字符串传递给
find()
将自动调用构造函数并创建一个临时test
结构仅包含相关键。请注意,在这种特殊情况下,构造函数不得显式声明。I suggest you
operator<
andoperator==
to your struct instead of overloading the global operator, I find it much cleaner; example:Now on to your real problem - your are passing a string to the
find()
function, but it only accepts structs of typetest
. In order to do so, add a constructor for automatic conversion, so the final struct would look like this:Then passing a string to
find()
would automatically call the constructor and create a temporarytest
struct containing only the relevant key. Note that in this special case, the constructor must not be declaredexplicit
.为了能够将结构放入
set
中,您必须为结构指定operator<
。您可以使operator<
返回比较相应字符串成员的结果。为了能够使用
find
,您可以为结构指定operator==
,以便在相应的字符串成员相等时返回true
。示例:
如果您想使用
string
参数调用find()
,您可以为您的test
从string
提供隐式构造函数code> struct 例如这样:但是使用隐式构造函数并不是一个好的技术,因为它可能会导致代码中更远的地方出现一些不可预测的转换。
To be able to put your structs into
set
you have to specifyoperator<
for your struct. You can make theoperator<
return result from comparing corresponding string members.To be able to use
find
you can specifyoperator==
for your struct to returntrue
if corresponding string members are equal.Sample:
If you want to call
find()
withstring
parameter you can provide an implicit constructor fromstring
for yourtest
struct for example like this:But usage of implicit constructors isn't a good technique, because it can lead to some unpredictable conversions somewhere further in your code.
首先,为了使
std::set::find ()
与您的struct
一起使用,您不需要指定operator==
,如 std::set:但是,您的实际问题是,您无法在 C++14。在 C++14 之前,
find()
需要一个元素作为参数,其类型与集合中存储的元素类型匹配。对于您的情况,这意味着您必须提供test
的实例。但是,由于您的operator<
仅比较key
变量,因此您可以对data
变量使用虚拟值,例如,如下所示:输出:
请注意,仅比较
key
变量的operator<
会产生副作用:只能存储test
的两个实例如果它们的key
变量不同,即使它们的data
变量不同。例如,如果将以下代码附加到上面的代码中,则不会(再次)插入newmember
:输出:
因此,如果您想存储具有相同键的多个元素,那么您可能必须选择不同的容器。
无论如何,如果一组
struct
适合您,并且您可以使用 C++11,那么你还可以使用 lambda表达式而不是为您的
struct
定义operator<
:Ideone 上的代码
C++14
从 C++14 开始,您可以使用 < code>find() 进行“透明比较”,如
std::set::find()
。这意味着,您可以找到一个与给定参数等价的元素。
详细来说,这意味着您必须定义
operator<
和您的集合,如下所示:然后您可以按照您预期的方式执行
find()
操作:输出:
Ideone 上的代码
First and foremost, in order to make
std::set::find()
work with yourstruct
, you don't need to specifyoperator==
, as explained for std::set:However, your actual problem is, that you can't search for parts of your
struct
by usingfind()
prior to C++14. Prior to C++14,find()
expects an element as argument, whose type matches the type of elements stored in the set. For your case, this means that you have to provide an instance oftest
. However, as youroperator<
compares only thekey
variables, you can use a dummy value for thedata
variable, for example, as follows:Output:
Please be aware that your
operator<
which compares only thekey
variables has a side effect: Two instances oftest
can only be stored in the set if theirkey
variables are different, even if theirdata
variables are different. For example, if you append the following code to the code above, thennewmember
will not be inserted (again):Output:
Consequently, if you want to store multiple elements with the same key, then you might have to choose a different container.
Anyway, if a set of
struct
is fine for you and you can make use of C++11, then you can also use a lambda expressioninstead of defining
operator<
for yourstruct
:Code on Ideone
C++14
Since C++14, you can use
find()
to do a "transparent comparison" as explained onstd::set::find()
.This means, that you can find an element that compares equivalent to the given argument.
In detail this means, that you have to define
operator<
and your set as follows:Then you can perform your
find()
operation as you would have expected it to work:Output:
Code on Ideone
只有你必须重写operator<()函数来增强查找功能。
在您的情况下,只需将运算符<()函数替换为..
Only you have to override operator<() function to enhance find function.
In your case simply replace operator<() function as..