Does a standard container return an instance of the contents of the container?

If I have a function that returns an STL container, do I get a copy of the entire contents of the standard container?

eg. It:

void Foo( std::vector< std::string >* string_list ); 

better than that:

 std::vector< std::string > Foo(); 

It doesn't matter what is in the container? For example, it will return the container as follows:

 struct buzz { int a; char b; float c; } std::map< int, buzz > Foo(); 

will be a more expensive operation than this:

 std::map< int, int > Foo(); 

Thanks PaulH


Edit: This is with C ++ 03. The C ++ 0x solution is unfortunately unacceptable.

Edit2: I am using the Microsoft Visual Studio 2008 compiler.

+4
source share
5 answers

C ++ 03 is likely to do (named) return value optimization (google RVO and NRVO).

If this optimization is not applicable, C ++ 0x will do the semantics move .

+6
source

I was not 100% sure, but NO (thanks to the commentators):

 #include <vector> #include <iostream> #define LOCAL_FUN struct A { A() { std::cout << "default ctor" << std::endl; } A(const A &a) { std::cout << "copy ctor" << std::endl; } }; #ifdef LOCAL_FUN std::vector<A> *pVec = NULL; #endif std::vector<A> func() { std::vector<A> vec; #ifdef LOCAL_FUN pVec = &vec; #endif vec.push_back(A()); std::cout << "returning" << std::endl; return vec; } int main(int argc, char *argv[]) { std::vector<A> ret = func(); #ifdef LOCAL_FUN if (pVec) { std::cout << pVec->size(); } #endif } 

(since LOCAL_FUN):

 default ctor copy ctor returning 1 

Editing: some more playing with the code led me to some fun with local variables (LOCAL_FUN). So a really bad compiler that doesn't optimize copying can really break this code ...

+3
source

Yes, it will contain a copy of the container, but do not use void Foo( std::vector< std::string >* string_list ); . Use void foo( vector<string>& string_list); .

Or just switch to C ++ 0x and use a compiler that already moves the optimizations implemented in the library.

+2
source

The first compiler should exclude building a copy if it fails, and then move it if it cannot then copy. Therefore, if you have a really bad compiler, you run the risk of doing additional damage to the extra copy. See this discussion for more details.

0
source

It depends on the constructor of the container copy. C ++ matters in the semantics of values. Therefore, when you return a vector for the Foo () function, it will be returned using the semantics of the values, i.e. To copy the value of the vector, the copy constructor will be called. In this case, the copy constructor std :: vector creates a new container and copies the values. In the case of passing a pointer to a container, you will have to allocate memory, if you have not yet allocated it, so that the pointer points to the actual container, and not to a null value. From the point of view of programming practice, this is not very good, because you leave the semantics open for interpretation. A better idea would be to pass a reference to the container and let the function fill the container with the desired elements.

0
source

Source: https://habr.com/ru/post/1340234/


All Articles