这是我的代码的一个愚蠢的版本,基本上我试图将STL SET作为函数参数传递但我无法这样做。我收到以下错误
错误:无法转换 'std :: set,std :: allocator为'int' 争论'1'到void foo(int)
错误:模板争论1无效
错误:模板争论2无效
错误:模板争论3无效
这是错误源自
的代码示例#include <iostream>
#include <set>
using namespace std;
void foo(set<foobar>);
class foobar
{
public:
int x;
};
int main()
{
set<foobar> foobar_set;
foo(foobar_set);
}
void foo(set<foobar> foobar_set)
{
}
问题:如何将STL集作为函数参数传递?
STL集存在多长时间,本地范围或全局范围??
答案 0 :(得分:8)
让我们按顺序考虑事情,编译器(大多数)的方式。当我们看了这么多代码时:
#include <iostream>
#include <set>
using namespace std;
void foo(set<foobar>);
...... foobar
是什么类型的?简短回答:根据我们目前所看到的情况,我们不知道 - 编译器也没有。在 foo
的定义之后将foobar
的声明移至(取决于它)。
class foobar
{
// ...
};
void foo(set<foobar>); // now the compiler knows what `foobar` means
int main()
{
set<foobar> foobar_set;
foo(foobar_set); // so now this can work
}
现在有点补充:你真的不想通过值传递set<whatever>
的机会非常好 - 这将导致复制整个集合。您可能希望通过const引用传递它:
void foo(set<foobar> const &);
...并确保您对foo
的定义匹配:
void foo(set<foobar> const &) {}
对于“小”类型(例如char
,short
,int
),您通常希望按值传递。对于(可能)与set<whatever>
传递(const
)一样大的东西,通常首选参考。这不是总是更好,但它通常至少是可以接受的。在合适的情况下通过值传递可以更快,但它也可能更慢 - 有时很多更慢,所以除非你确定你知道你在做什么,否则通过{{1引用通常是安全的选择。
答案 1 :(得分:3)
我认为问题在于:
void foo(set<foobar>);
class foobar
{
public:
int x;
};
当您进行原型设计foo
时,尚未声明类型foobar
,并且编译器不知道该怎么做。当我尝试编译此at ideone时,我收到的第一条错误消息是
prog.cpp:5:14: error: ‘foobar’ was not declared in this scope
void foo(set<foobar>);
您可以通过重新排序foobar
和原型的定义或通过前向声明foobar
来解决此问题。完成后,错误应该清除。将set
s作为参数传递没什么特别的。
希望这有帮助!
答案 2 :(得分:3)
当声明foo()时,foobar类尚未声明。只需在foo()之前移动foobar的定义就可以解决您的问题。 希望这会有所帮助。
答案 3 :(得分:0)
在声明函数之前尝试声明foobar类的声明。 如果您不想将完整的课程移到foo函数之上,这也是推荐的方法。
class foobar;
void foo(set<foobar>); // now the compiler knows what `foobar` means
我确信这可以解决您的问题,或者至少会给您带来新的错误;)