我有以下代码,一个试图将对set(foo)中的对象的引用传递给另一个函数(goo)的函数。
/**************** working ***************/
{
std::set<MyStruct> foo;
MyStruct abc = *foo.begin();
goo(abc);
}
int goo(MyStruct & st)
{
//some code here
}
/**************** not working ***************/
{
std::set<MyStruct> foo;
goo( *(foo.begin()) );
}
int goo(MyStruct & st)
{
//some code here
}
错误列表:
>file.cpp:190:45: error: no matching function for call to 'goo(const MyStruct&)'
>file.cpp:190:45: note: candidate is:
>file.h:33:9: note: int goo(MyStruct&)
>file.h:33:9: note: no known conversion for argument 1 from 'const MyStruct' to 'MyStruct&'
第一个版本编译正常,而第二个版本报告错误。我已经看过const关键字了,但是我并没有将const括在任何地方,而且这个集合不是const。你能解释一下我做错了吗?
答案 0 :(得分:7)
set
包含具有唯一值的不可变对象,但goo
需要非const引用。更改goo
以获取const引用,使用除集合之外的其他内容,或者创建对象的副本。只要对象在集合中,就无法修改,因此无法将其传递给修改(或可以修改)对象值的函数。
答案 1 :(得分:1)
第一个版本有效,因为您要将const MyStruct&
分配给MyStruct
类型的变量,在这种情况下,复制构造函数会接受。调用goo
时变量abc
是可修改的。
您传递begin
的解除引用的第二个版本,关联容器的键是 const (这是因为如果有关键可以更改,那将非常糟糕插入容器,顺序可能搞砸了,Visual Studio在某些版本之前就遇到了这个问题)在这种情况下begin
返回错误说const MyStruct&
(不可修改)。
如果goo不会更改参数的值,请添加const
,如果它修改了其值,请使用第一种情况。如果您需要使用修改值更新集,请擦除并重新插入。
答案 2 :(得分:0)
在第一种情况下,将* foo.begin()分配给变量(不是const)。
在第二种情况下,您可以立即将* foo.begin()(内部表示为const引用)发送到您的方法。