No Matching Function for Call to Class Constructor

No matching function for call to Class Constructor

The member center_pt is being default initialized and such an operation will call the no arguments default constructor Point(). This however is not defined in the Point class and therefore gives you the error you got.

Circle::Circle(const Point& center, double radius)
{
center_pt = center; //<-- this is an assignment
//default init has already occurred BEFORE this point
radius_size = radius;
}

Before you can assign to center_pt here you need something to assign to. The compiler therefore tries to default initialize center_pt for you first before trying to do the assignment.

Instead if you use the member initializer list you can avoid the problem of the default construction followed by assignment:

Circle::Circle(const Point& center, double radius):
center_pt(center),
radius_size(radius)
{
}

When you create a class you are essentially setting aside the memory to store the various members within that class. So imagine center_pt and radius_size as places in the memory that those values get stored in for each instance of your class. When you create a class those variables have to get given some default values, if you don't specify anything you get the default constructed values, whatever those are. You can assign values later to those locations but some initialization will always occur at the time of class creation. If you use the initializer list you get to explicitly specify what gets placed in the memory the first time around.

By using the member initializer list here your members are being constructed appropriately the first time around. It also has the benefit of saving some unnecessary operations.

No matching function for call to default constructor

The compiler is not able to generate a default constructor for B because the constructor of B needs to call the constructor of A. The constructor of A expects an int and the compiler does not know what value to pass to it. This means you need to declare a constructor of B yourself that takes care of this.

You can either have the constructor of B also take an int and use that or for example have B use a fixed value instead:

struct B: A
{
B() : A(10) {}

B(int x) : A(x) {}
};

But you have to pass something to A's constructor.

No matching function call in constructor

error: no matching function for call to 'Board::Board()'

means that class Board is missing the deafault constructor. In the constructor of Solver you are probably doing something like:

Solver::Solver(const Board &board_c, int max_moves_c) {
Board b; // <--- can not construct b because constructor is missing
...
}

so you either have to define the default constructor or invoke the appropriate constructor with some arguments.

"And then it lists the candidates which are the Board constructors."

That's because compiler wants to help you so it lists possible constructors that are actually available (defined).

C++: no matching function for call: why is an empty constructor needed?

(All ISO Standard references below refer to N4659: March 2017 post-Kona working draft/C++17 DIS)


As per [class.base.init]/9, the mya member of b, which is of type a, is default-initialized, but a defines no default constructor:

In a non-delegating constructor, if a given potentially constructed
subobject is not designated by a mem-initializer-id
(including the
case where there is no mem-initializer-list because the constructor
has no ctor-initializer), then

  • (9.1) if the entity is a non-static data member that has a default member initializer [...] the entity is initialized from its default member initializer as specified in [dcl.init];
  • (9.2) otherwise, if the entity is an anonymous union or a variant member ([class.union.anon]), no initialization is performed;
  • (9.3) otherwise, the entity is default-initialized.

Here, as mya does is not declared along with a default member initializer, [class.base.init]/9.3 applies.

The example of [class.base.init]/9 even cover this particular case:

[...] [ Example:

struct A {
A();
};

struct B {
B(int);
};

struct C {
C() { } // initializes members as follows:
A a; // OK: calls A​::​A()
const B b; // error: B has no default constructor
int i; // OK: i has indeterminate value
int j = 5; // OK: j has the value 5
};

— end example ]

You can resolve it either by providing a default member initializer for mya, such that [class.base.init]/9.1 applies

class b {
a mya{42}; // default member initializer
int j;

public:
b(int);
};

or, use a member initializer list in the definition of the constructor of b; b::b(int), such that [class.base.init]/7 applies:

The expression-list or braced-init-list in a mem-initializer is used
to initialize the designated subobject (or, in the case of a
delegating constructor, the complete class object) according to the
initialization rules of [dcl.init] for direct-initialization.
[ Example:

struct B1 { B1(int); /* ... */ };
struct B2 { B2(int); /* ... */ };
struct D : B1, B2 {
D(int);
B1 b;
const int c;
};

D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { /* ... */ }
D d(10);

— end example ] [...]

thus direct-initializing the mya member:

b::b(int i2) : mya(i2) {
// ^^^^^^^- member initializer list
j=2*i2;
}

error: no matching function for call to ‘Point::Point()

The first problem is that when the constructor Circle::Cirlce(Point, int) is implicitly called by the compiler, before executing the body of that ctor, the data members centre and radius are default initialized. But since you've provided a user-defined ctor Point::Point(int, int) for class Point, the compiler will not synthesize the default ctor Point::Point(). Thus, the data member centre cannot be default initialized.

To solve this you can use constructor initializer list as shown below. The constructor initializer list shown below, copy initialize the data member centre instead of default initializing it.

class Point {
private:
int x, y;
public:
Point(int X, int Y) {
x = X;
y = Y;
}

};
class Circle {
private:
int radius;
Point centre;

public:
//--------------------------vvvvvvvvvvvvvvvvvvvv--->constructor initializer list used here
Circle(Point q, int r): radius(r), centre(q)
{

}
};

int main() {
Point obj = Point(3, 4);
Circle circleObj(obj,4);
}

Demo

Additionally, you had 2 objects with the same name obj inside main.



Related Topics



Leave a reply



Submit