当我学习C ++时,他们警告我不要使用STL。这是新的,错误的,低效的。最近我发现自己为一个新项目创建了一个容器,并意识到它可能是NIH的情况,我应该尝试STL< vector>。
不幸的是它不起作用。
#include <stdio.h>
#include <stdlib.h>
#include <vector>
class test {
public:
int x;
};
int main(int argc,char *argv[]) {
std::vector<test> obj;
test *tmp=new test();
tmp->x=42;
obj.push_back(tmp);
}
g ++警告我,push_back没有匹配函数,而push_back需要const value_type&amp;作为参数。我已经尝试过很多演员来强迫这一点,但它拒绝让步。
我现在浪费了更多的时间尝试以“正确”的方式进行操作,而不是编写另一个容器并进行调试。
如果这听起来像是愤怒和沮丧,那么你就是敏锐的。我已经发现了几个像我一样的问题,但答案非常难以理解。如果这是一个火焰会飞的地方,我会期待为此加油。我已经潜伏了stackoverflow几年,我打赌有人可以“像我五岁那样解释它。”
是否有单行咒语迫使演员工作?如果没有,这些载体应该如何使用?
答案 0 :(得分:11)
丢失指针
std::vector<test> obj;
test tmp;
tmp.x=42;
obj.push_back(tmp);
你有一个test
而不是test*
的向量,所以我不确定你为什么试图涉及指针。 STL的大量优势之一是它允许你避免使用指针,作为一个经验丰富的C ++,我相信你知道这是错误的主要原因。
答案 1 :(得分:3)
做这两件事之一
std::vector<test*> obj;
test *tmp=new test;
tmp->x=42;
obj.push_back(tmp);
或者
std::vector<test> obj;
test tmp;
tmp.x=42;
obj.push_back(tmp);
如果声明vector
个test
个对象,则推送test
个对象。
如果您声明了vector
test
个指针,那么请推送test *
。
答案 2 :(得分:1)
随着失去指针@John(我认为非常正确)建议,我将添加一个ctor到你的test
类:
class test {
int x;
public:
test(int x) : x(x) {}
};
这可以用于隐式转换,因此您也可以跳过tmp
变量,留下类似的内容:
std::vector<test> t;
t.push_back(42);
...并且编译器将使用ctor自动将42
转换为test
对象,并将x
值设置为42
。
如果您想防止意外将随机int
转换为test
,您可以选择中途点。制作合作伙伴explicit
,并明确转换为push_back
:
class test {
int x;
public:
explicit test(int x) : x(x) {}
};
// ...
std::vector<test> t;
t.push_back(test(42));
哦,我应该提一下其他细节:假设您正在使用(相当)新的编译器,您可能希望使用emplace_back
而不是push_back
。如果有机会,它将创建新对象,而不是将其复制到向量中。对于像test
这样的小类(仅包含单个int
),它不会产生任何真正的差别,但对于复制成本较高的大小,差异可能很大。
答案 3 :(得分:1)
您不应该在std集合中存储C ++指针。您建议按照John建议自己存储对象。使用原始指针会产生许多非常棘手的内存错误 如果他认为STL是马车的话,也许你的老师已经这样做了。它非常强大。如果将大对象存储在集合中,因为这些将被复制,STL似乎效率低下,这在时间和内存上都很昂贵。因此,对低效率的看法也是错误的。 诀窍是使用smart pointers。这使得堆分配更容易,并且与STL一起工作得非常好。它是高效的,而不是所有的车。写自己要好得多。