4

I have following code

class base
{
    private:
            int k;
    public:
            base(const base& b){ this->k = b.k; cout<<"  c-ctor "<<endl; }
            base(int a = 10){ k = a; cout<<"  a = "<<a<<endl; }
            friend const ostream& operator<<(ostream& out, base& b)
            {
                return out<<b.k<<endl;
            }
};

int main()
{
    base b, b1(2);
    vector<base> vec = {b, b1};
    cout<<"  check point "<<endl;
    for(auto& elem : vec)
        cout<<"   "<<elem;
    cout<<endl;
    return 0;
}

Output :

1-      a = 10                                                                                                                                                                                                       
2-      a = 2                                                                                                                                                                                                        
3-      c-ctor                                                                                                                                                                                                       
4-      c-ctor                                                                                                                                                                                                       
5-      c-ctor                                                                                                                                                                                                       
6-      c-ctor                                                                                                                                                                                                       
7-      check point                                                                                                                                                                                                  
8-       10                                                                                                                                                                                                          
9-       2  

Could anybody please explain why 4 calls for copy constructor, i understand 2 calls while copying object in container. How 4?

instance
  • 1,366
  • 15
  • 23

1 Answers1

8

The reason being that the initialization vector<base> vec = {b, b1}; creates a std::initializer_list<base> and passes it to the appropriate vector constructor. Which then proceeds to copy it further.

You can limit the number of copies by directly initializing the members of the std::initializer_list<base>, instead of creating named objects. Something like this:

vector<base> vec = {{}, {2}};

Or eliminate the superfluous copying completely by reserveing memory in the vector first, and then emplaceing the objects into it.

vector<base> vec;
vec.reserve(2);
vec.emplace_back();
vec.emplace_back(2);
StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • 1
    `vec = {{}, {2}}` will use 2 "casual" constructors and 2 copy ones. If performance is needed, move constructors should be provided. – ilotXXI Dec 15 '16 at 09:46
  • In the case vec = {{}, {2}} move constructor not called. – user1438832 Dec 15 '16 at 10:13
  • @user1438832 it will simply call 2 constructor and 2 copy ctro, you need to define move constructor to call it using move(b), move ctor is not provided by compiler like defauly, copy ctor and assignnment operator. – instance Dec 15 '16 at 10:46
  • My point is even move constructor is defined how can i use it in vec = {{}, {2}}. I can use it in push_back for example. – user1438832 Dec 15 '16 at 11:01
  • 1
    @user1438832 Initializer lists are weird beasts, see http://stackoverflow.com/questions/8193102/initializer-list-and-move-semantics – Rerito Dec 15 '16 at 12:18