老程序员需要STL机密

时间:2013-08-31 19:40:11

标签: c++ vector stl

当我学习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几年,我打赌有人可以“像我五岁那样解释它。”

是否有单行咒语迫使演员工作?如果没有,这些载体应该如何使用?

4 个答案:

答案 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);

如果声明vectortest个对象,则推送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一起工作得非常好。它是高效的,而不是所有的车。写自己要好得多。