初始化std :: string的std :: vector

时间:2013-12-17 12:37:17

标签: c++ stdvector stdstring

在使用一些遗留代码的项目中工作时,我发现了这个功能:

std::vector<std::string> Object::getTypes(){
    static std::string types [] = {"type1","type2", "type3"};
    return std::vector<std::string> (types , types +2);
}

我可能会把它写成:

std::vector<std::string> Object::getTypes(){
    std::vector<std::string> types;
    types.push_back("type1");
    types.push_back("type2");
    types.push_back("type3");
    return types;
}

这仅仅是一种风格选择还是我缺少的东西?任何帮助将不胜感激。对不起,如果这太基础了。

更新 实际上发现覆盖相同方法的不同类可以这样或那样做,所以它更加含糊不清。我会让它们完全相同,但如果有的话,我会更喜欢更好的方法。


修改

请注意,上述遗留代码不正确,因为它仅使用数组的前两个元素初始化向量。但是,此错误已在评论中讨论过,因此应予以保留。

正确的初始化应该如下所示:

...
    return std::vector<std::string> (types, types + 3);
...

5 个答案:

答案 0 :(得分:9)

如果你有一个支持C ++ 11的编译器和库,那么返回一个初始化列表就足够了:

std::vector<std::string> Object::getTypes(){
    return {"type1","type2", "type3"};
}

答案 1 :(得分:5)

您找到的代码效率更高(因为types[]只分配一次而push_back可以/将导致重新分配)。虽然区别很小,除非你在一个(相对较大的)循环中调用getTypes,否则它根本不重要(即使你在一个循环中调用它也可能很重要)大循环)。

因此,除非它产生具体的性能问题,否则它是一种风格选择。

答案 2 :(得分:3)

基本上它是一种风格选择。我可能会做更像

的事情
std::vector<std::string> Object::getTypes(){
    static std::string types [] = {"type1","type2", "type3"};
    return std::vector<std::string> (types, 
                   types + (sizeof(types)/sizeof(std::string)) );
}

可让您更改类型中的内容数量,而无需记住更新下一行中的计数。

答案 3 :(得分:1)

第一个示例中的数组types声明为static。这意味着它只在内存中存在一次。因此返回的内容有三个选项,它们存在于静态内存中。然后,当您创建要返回的向量时,您可以通过将数组的开头和结尾作为迭代器传递来一次性分配它的内存。

通过这种方式,您不会连续调用push_back,这意味着向量不必重新分配其内部内存块。

此外,当向量构建为返回调用的一部分时,较旧的编译器将更容易执行return value optimization

答案 4 :(得分:0)

我喜欢使用这种初始化方式与迭代器(以及C ++ 11的统一初始化和初始化列表)的一个原因是它有助于将数据与代码分离。

重复push_back很多次感觉很糟糕,因为我迫切需要重构它。此外,当您真的只需要使用数据初始化容器时,您希望查看数据列表,而不是真正生成数据的代码。您在原始版本中找到的方法更符合该原则。