老程序员需要STL的秘密

Old programmer needs STL secrets

本文关键字:秘密 STL 程序员      更新时间:2023-10-16

当我得知C++时,他们警告我不要使用STL。 它是新的,有缺陷的,效率低下的。 最近,我发现自己为一个新项目创建了一个容器,并意识到这可能是NIH的一个案例,我应该尝试STL

不幸的是,它不起作用。

#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&作为参数。 我尝试过很多演员来强迫这样做,但它拒绝让步。

我现在浪费了更多的时间尝试以"正确"的方式做到这一点,而不是编写另一个容器并调试它所花费的时间。

如果这听起来像是愤怒和沮丧,那么你是敏锐的。 我已经找到了几个像我这样的问题,但答案证明非常难以理解。 如果这是一个火焰会飞的地方,我希望为此干杯。 我已经在stackoverflow周围潜伏了几年,我敢打赌有人可以"像我五岁一样解释它"。

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

丢失指针

std::vector<test> obj;
test tmp;
tmp.x=42;
obj.push_back(tmp);

你有一个testtest*的向量,所以我不确定你为什么试图涉及指针。STL的巨大优势之一是它允许您避免指针,作为一名经验丰富的C++,我相信您知道这是错误的主要原因。

做这两件事之一

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

如果声明test对象的vector,则push_back test对象。如果声明test指针的vector,则push_back test *

不应在 std 集合中存储C++指针。 您可以按照 John 的建议存储对象本身。 使用原始指针会导致许多非常棘手的内存错误。
也许你的老师已经这样做了,如果他认为STL有问题的话。它真的很强大。 如果将大型对象存储在集合中,则 STL 似乎效率低下,因为这些对象将被复制,这在时间和内存上都很昂贵。因此,关于效率低下的信念也是错误的。诀窍是使用智能指针。 这些使堆分配变得更加容易,并且可以出色地与 STL 配合使用。然后它是有效的,而且根本没有问题。 写自己比任何时候都合理得多。

除了按照@John(在我看来非常正确(的建议丢失指针外,我还会在您的test中添加一个 ctor:

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,你可以去一个半途而废。使 ctor 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(,它不会产生任何真正的区别,但对于复制成本很高的大型类,差异可能很大。