C++ default constructor is not used at runtime, but required at compile time

  • A+
Category:Languages

Here is my code. If I remove default constructor, there will be error below. But if I add a default constructor, it will have no issues compiling and running. Wondering why? I am especially confused since default constructor is not used at all in runtime, why it is required at compile time?

#include <iostream> #include <vector> #include <string>  class Foo {  public:   //Foo();   Foo(const std::string& name, double score);   Foo(const Foo& other);   Foo(Foo&& other);   const std::string& name() const { return name_; }   double score() const { return score_; }   private:   std::string name_;   double score_; };  /* Foo::Foo() {   std::cout << "In default constructor " << std::endl;   name_ = "foo";   score_ = 1.0; }*/  Foo::Foo(const std::string& name, double score) : name_(name), score_(score) {   std::cout << "In parametered constructor " << std::endl; }  Foo::Foo(const Foo& other) {   std::cout << "In copy constructor " << std::endl;   name_ = other.name();   score_ = other.score(); }  Foo::Foo(Foo&& other)     : name_(std::move(other.name())), score_(std::move(other.score())) {   std::cout << "In move constructor " << std::endl; }  int main(int argc, char** argv) {   std::vector<Foo> students;   students.emplace_back("name1", 4.0);   students.emplace_back("name2", 5.0);   std::cout << "resizing begin " << std::endl;   students.resize(1);   for (Foo student : students) {     std::cout << "student name: " << student.name()               << " student score: " << student.score() << std::endl;   }   return 0; } 

Error message when there is no default constructor,

Error:   required from 'static _ForwardIterator std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = Foo*; _Size = long unsigned int; bool _TrivialValueType = false]' 

Successful run output when there is default constructor,

In parametered constructor  In parametered constructor  In copy constructor  resizing begin  In copy constructor  student name: name1 student score: 4 


The issue is your call to resize (specifically, students.resize(1)); when that line is removed, the code compiles. The issue is that resize has to initialize the new elements if it wasn't large enough, thus it needs the default constructor. If you want to shrink the size of your students without ensuring it's a sufficient size, you can use erase (Max Vollmer has a specific example).

Information on resize is available at cppreference. You're falling into the first (single argument) form.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: