Q:

Why default constructor doesn't work for `vector::emplace_back`

#include <vector>
#include <string>
#include <iostream>

struct PersonA {
  int age; std::string name;    
  PersonA(int _age, const std::string& _name) : age(_age), name(_name) {}
};

struct PersonB {
  int age; std::string name;    
  PersonB(int _age, const std::string&& _name): age(_age), name(_name) {}
};

struct PersonC {
  int age; std::string name;
};

int main()
{
  std::vector<PersonA> personA;  
  personA.emplace_back(10, "nameA");   // fine

  std::vector<PersonB> personB;  
  personB.emplace_back(10, "nameB");   // fine

  std::vector<PersonC> personC;  
  //personC.emplace_back(10, "nameC"); // (the implicit move constructor) not viable
                                       // (the implicit default constructor) not viable

  personC.emplace_back();              // UPDATE: fine.
}

Question> Why does vector::emplace_back request explicit definition of constructor otherwise the following line doesn't work?
// why it cannot make use of the default constructor of PersonC?
personC.emplace_back(10, "nameC"); 

Also, vector::emplace_back doesn't support uniform intialization. Does this have sth to do with the above issue?
Thank you

A:

std::emplace_back() takes the arguments you provide to it and perfect-forwards them to the constructor of the value_type object it is supposed to create (in your case, PersonC).
Table 101 of the C++11 Standard specifies the semantics of emplace_back():

Expression: a.emplace_back(args)
Return type: void
Operational semantics: Appends an object of type T constructed with
std::forward<Args>(args)....

There is no constructor of PersonC that accepts an int and a const char* (or anything which could be constructed from an int and a const char*, respectively), hence the error.
In case you're wondering, the only constructors that a compiler can implicitly define are the default constructor, the copy constructor, and the move constructor.

