I have the following two files
foobar.h
#ifndef FOOBAR_H
#define FOOBAR_H
#include <cstring>
class Foo {
public:
int x;
Foo(int x);
};
class Bar {
public:
char* name;
Foo foo;
Bar(Foo foo);
};
#endif // FOOBAR_H
and foobar.cpp
#include "foobar.h"
Foo::Foo(int x) {
// Do something
}
Bar::Bar(Foo foo) {
// Do something
}
Attempting to compile these with g -c foobar.cpp -o foobar.o
results in the following error:
foobar.cpp: In constructor ‘Bar::Bar(Foo)’:
foobar.cpp:9:17: error: no matching function for call to ‘Foo::Foo()’
Bar::Bar(Foo foo) {
^
foobar.cpp:5:1: note: candidate: ‘Foo::Foo(int)’
Foo::Foo(int x) {
^~~
foobar.cpp:5:1: note: candidate expects 1 argument, 0 provided
In file included from foobar.cpp:1:
foobar.h:5:7: note: candidate: ‘constexpr Foo::Foo(const Foo&)’
class Foo {
^~~
foobar.h:5:7: note: candidate expects 1 argument, 0 provided
foobar.h:5:7: note: candidate: ‘constexpr Foo::Foo(Foo&&)’
foobar.h:5:7: note: candidate expects 1 argument, 0 provided
As far as I understand the output of g is that it requires me to have a default constructor for foo. Why? I wish to pass a foo object to the constructor of bar, why would it need to invoke a default constructor anywhere? I do not want to have a no-args constructor anyways, since I NEED that x has a specific user defined value.
CodePudding user response:
You are trying to default construct a Foo
here:
Bar::Bar(Foo foo) {
// the member variable `foo` would have been default constructed here
// Do something
}
But Foo
doesn't have a default constructor. One possible solution would be to initialize it in the member initializer list:
Bar::Bar(Foo foo) : foo(std::move(foo)) { // now uses the move constructor instead
// Do something
}