Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing std::vector of std::string

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);
...
like image 660
Andres Bucci Avatar asked Dec 17 '13 12:12

Andres Bucci


People also ask

How do you create a vector of strings?

How to Create a Vector of Strings in C++ The program begins with the inclusion of the iostream library, which is needed for keyboard input, and output to the terminal (screen). This is followed by the inclusion of the string library, which is needed for automatic composing of strings.

How do you initialize a vector by its default value?

Specifying a default value for the Vector: In order to do so, below is the approach: Syntax: // For declaring vector v(size, default_value); // For Vector with a specific default value // here 5 is the size of the vector // and 10 is the default value vector v1(5, 10);


3 Answers

If you have a C++11 capable compiler and library, returning an initializer list should be enough:

std::vector<std::string> Object::getTypes(){
    return {"type1","type2", "type3"};
}
like image 139
Some programmer dude Avatar answered Oct 13 '22 05:10

Some programmer dude


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

As such, unless it creates a concrete performance problem, it's a style choice.

like image 25
utnapistim Avatar answered Oct 13 '22 03:10

utnapistim


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.

like image 24
Michael Kohne Avatar answered Oct 13 '22 03:10

Michael Kohne