Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning stl containers from functions

What is the best way (performance-wise) of returning stl containers from a function? The container returned would usually contain several thousands of items.

Method 1:

typedef std::list<Item> ItemContainer;

ItemContainer CreateManyItems() {
    ItemContainer result;

    // fill the 'result' ...

    return result;
}

ItemContainer a = CreateManyItems();

Method 2:

void CreateManyItems(ItemContainer &output) {
    ItemContainer result;

    // fill the 'result' ...

    output.swap(result);
} 

ItemContainer a;
CreateManyItems(a);

Method 3:

void std::auto_ptr<ItemContainer> CreateManyItems() {
    std::auto_ptr<ItemContainer> result(new ItemContainer);

    // fill the 'result' ...

    return result;
}

std::auto_ptr<ItemContainer> a = CreateManyItems();

Or is there any better way?

like image 646
Juraj Blaho Avatar asked May 13 '11 11:05

Juraj Blaho


People also ask

How do I return a container in C++?

The container returned would usually contain several thousands of items. Method 1: typedef std::list<Item> ItemContainer; ItemContainer CreateManyItems() { ItemContainer result; // fill the 'result' ... return result; } ItemContainer a = CreateManyItems();

Are STL containers passed by reference?

@BjörnPollex Yes! I forgot to mention that.

Are STL containers allocated on heap?

std::vector always has its buffer allocated on heap. So regardless of where the vector itself is allocated resizing it will only affect the heap.


2 Answers

None: if you just want to fill std::list with items, then you can use std::fill or std::fill_n or a combination of standard library functions.

It's not clear how exactly you want to fill your list, so I can't comment on your code precisely. If possible, use the standard library. If you cannot, then go for Method 1, and the compiler may optimize away the return value in your code eliding the unnecessary copies, as most compilers implement RVO.

See these articles on copy elision and return value optimization (RVO):

  • Copy elision – Wikipedia
  • Copy elision – cppreference

Related questions:

  • In C++, is it still bad practice to return a vector from a function?
  • Returning a c++ std::vector without a copy?

An article by Dave Abrahams:

  • Want Speed? Pass by Value

I would still emphasize this: have you seen all the generic functions provided by <algorithm> header? If not, then I would suggest you to first look into them and see if any of them (or a combination of them) can do what you want to do in your code.

If you want to create and fill the list, then you can use std::generate() or std::generate_n function.

like image 156
Nawaz Avatar answered Sep 20 '22 13:09

Nawaz


I usually use method 4 (almost identical to method 2):

void fill(ItemContainer& result) {
    // fill the 'result'
}

ItemContainer a;
fill(a);
like image 23
Tamás Avatar answered Sep 19 '22 13:09

Tamás