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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With