c++c++11object-constructionaggregate-type

What's the difference between push_back({ "George", 1 }) and push_back(Student("Jack", 10));


I was just wondering if there's a difference between the following two lines:

objStudents.push_back({ "George", 1 });
objStudents.push_back(Student("Jack", 10));

Is one way more efficient than the other? Or is it just a different syntax that completes the same task?


Solution

  • Assumming Student has a constructor with the right arguments, the difference is that while objStudents.push_back(Student("Jack", 10)); always compiles, objStudents.push_back({ "George", 1 }); only compiles if the constructor is not declared explicit. On the other hand, if Student is an aggregate (e.g. struct Student { string s; int i; };), then only objStudents.push_back({ "George", 1 }); compiles.

    Both forms are equally efficient if they compile - both construct Student from e.g. "George", 1 followed by invoking move (if exists) or copy constructor.

    In the case with a constructor, a more efficient form, which compiles even if the constructor is explicit, is objStudents.emplace_back("George", 1);, which constructs Student directly inside the vector and avoids the extra move or copy. Of course, "more efficient" here is theoretical - a compiler may be able to optimize away the extra operation in the form with push_back.