C++ 初始化 std::string 的 std::vector
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20634346/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Initializing std::vector of std::string
提问by Andres Bucci
While working in a project with some legacy code i found this function:
在使用一些遗留代码的项目中工作时,我发现了这个功能:
std::vector<std::string> Object::getTypes(){
static std::string types [] = {"type1","type2", "type3"};
return std::vector<std::string> (types , types +2);
}
I would probably have written this as:
我可能会这样写:
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;
}
Is this merely a style choice or is there something I'm missing? Any help would be greatly appreciated. Sorry if this is too basic.
这仅仅是一种风格选择还是我遗漏了什么?任何帮助将不胜感激。对不起,如果这太基本了。
Update:Actually found different classes that override the same method do it one way or the other, so It's even more ambiguous. I would make them all the same but would prefer the better approach, if there is one.
更新:实际上发现覆盖相同方法的不同类以一种或另一种方式执行此操作,因此更加模棱两可。我会让它们都一样,但更喜欢更好的方法,如果有的话。
Edit
编辑
Please note that the above legacy code is incorrect because it initializes the vector with only the first two elements of the array. However, this error has been discussed in the comments and thus should be preserved.
请注意,上述遗留代码是不正确的,因为它仅使用数组的前两个元素来初始化向量。但是,此错误已在评论中讨论过,因此应保留。
The correct initialization should have read as follows:
正确的初始化应该如下所示:
...
return std::vector<std::string> (types, types + 3);
...
采纳答案by Anthony
The array types
in the first example is declared static. This means it only exists once in memory. So there are three options for what to return and they live in static memory. Then, when you create the vector to return, you are able to allocate it's memory in one shot by passing the beginning and ending of the array as iterators.
第types
一个示例中的数组被声明为静态的。这意味着它在内存中只存在一次。因此,对于返回的内容有三种选择,它们都存在于静态内存中。然后,当您创建要返回的向量时,您可以通过将数组的开头和结尾作为迭代器传递来一次性分配它的内存。
By doing it this way, you don't have successive calls to push_back
which means the vector won't have to reallocate its internal block of memory.
通过这样做,您没有连续调用,push_back
这意味着向量不必重新分配其内部内存块。
Also, when the vector is constructed as part of the return call, older compilers will have an easier time of doing return value optimization.
此外,当向量被构造为返回调用的一部分时,较旧的编译器将更容易进行返回值优化。
回答by Some programmer dude
If you have a C++11 capable compiler and library, returning an initializer list should be enough:
如果你有一个支持 C++11 的编译器和库,返回一个初始化列表就足够了:
std::vector<std::string> Object::getTypes(){
return {"type1","type2", "type3"};
}
回答by utnapistim
The code you found is more efficient (because types[]
is only allocated once and push_back
can/will cause re-allocations). The difference though is marginal, and unless you call getTypes
in a (relatively big) loop it shouldn't matter at all (and probably it won't matter much even when you do call it in a big loop).
您找到的代码效率更高(因为types[]
只分配了一次并且push_back
可以/将导致重新分配)。尽管差异很小,除非您调用getTypes
(相对较大的)循环,否则它根本不重要(即使您确实在大循环中调用它也可能无关紧要)。
As such, unless it creates a concrete performance problem, it's a style choice.
因此,除非它造成具体的性能问题,否则它是一种风格选择。
回答by Michael Kohne
Basically it's a style choice. I'd probably do something more like
基本上这是一种风格选择。我可能会做一些更像
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)) );
}
which lets you change the number of things in types, without having to remember to update the count in the next line.
这使您可以更改类型中的事物数量,而不必记住更新下一行中的计数。
回答by Anthony
One reason I like to use this style of initialization with iterators (and C++11's uniform initialization and initializer lists) is that it helps separating data from code.
我喜欢在迭代器(以及 C++11 的统一初始化和初始化列表)中使用这种初始化风格的一个原因是它有助于将数据与代码分开。
Repeating push_back
a lot of times feels bad because I desperately need to refactor that. Also, when you really just need to initialize the container with data, then you want to see a list of the data, and not really code that generates data. The method you found in the original version matches that principle better.
重复push_back
很多次感觉很糟糕,因为我迫切需要重构它。此外,当您真的只需要用数据初始化容器时,您希望看到数据列表,而不是真正生成数据的代码。您在原始版本中找到的方法更符合该原则。