4

From what I understand about inheritance in C++ is that whenever the constructor of a child class is called, constructor of the parent class is called automatically. And as for templated constructors, data type of the template argument is infered automatically i.e. we don't need to specify template arguments separately. The program generates a compilation error which I don't seem to understand.

#include <iostream>
#include <list>
#include <algorithm>

using namespace std;

class A{
  public:
    int x;
    int y;
    int first(){
      return x;
    }
    int second(){
      return y;
    }
};

class C{
  public:
    float a,b;
    C(){
      a = 0.0f;
      b = 0.0f;
    }
    template<class T>
      C(T t){
        a = t.first();
        b = t.second();
      }
};

class D: public C{
  public:
    float area(){
      return a*b; 
    }
}

int main(){
  A a;
  a.x = 6;
  a.y = 8;
  C c(a);
  D d(a);
  cout<<c.a<<" "<<c.b<<" "<<d.area()<<endl;
}

Compilation error generated

test.cpp: In function ‘int main()’:
test.cpp:56:8: error: no matching function for call to ‘D::D(A&)’
test.cpp:56:8: note: candidates are:
test.cpp:44:7: note: D::D()
test.cpp:44:7: note:   candidate expects 0 arguments, 1 provided
test.cpp:44:7: note: D::D(const D&)
test.cpp:44:7: note:   no known conversion for argument 1 from ‘A’ to ‘const D&’

I have no idea what is happening here. Any ideas?

K-ballo
  • 80,396
  • 20
  • 159
  • 169
gibraltar
  • 1,678
  • 4
  • 20
  • 33

2 Answers2

6

D has to pass the constructor argument to C, since you are not using default constructors.

class D : public C {
public:
    template <typename T> D (T t) : C(t) {}
    float area () { /* ... */ }
};

The reason for the error is that you are trying to construct D with a parameter, but have not declared any constructor that would allow you to do so. Furthermore, you have to pass the parameter into C, otherwise the compiler will use C's default constructor.

The compiler error message can be analyzed like this.

test.cpp:56:8: error: no matching function for call to ‘D::D(A&)’

The compiler is complaining about:

D d(a);

And that it can't figure out how to construct a D when passed something of type A.

It then presents the two choices of constructors it knows about:

test.cpp:44:7: note: D::D()
test.cpp:44:7: note: D::D(const D&)

And it points out that for each one, there is a reason it can't use it. For the first one, it doesn't take any arguments. For the second one, it has no way to convert something of type A into type D.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • 1
    I agree that your solution likely works, and your reasons seem fine, but I would add that the 2 last lines in his error shows that the compiler is likely trying to "infer" in a copy constructor for D as well, which compilers CAN generate on their own. This additional error is also probably confusing the OP. – Kevin Anderson Jun 11 '12 at 18:16
  • @Kevin: Thanks for the feedback, I extended the explanation of the error messages. Regards. – jxh Jun 11 '12 at 18:24
1

From what I understand about inheritance in C++ is that whenever the constructor of a child class is called, constructor of the parent class is called automatically.

Careful: The constructor of the parent class is automatically called with the same arguments as the constructor of the child class.

As for the specific problem at hand: There is no constructor declared for class D. You'll get a default constructor and copy constructor as freebies, but not that template-based constructor in class C. Constructors aren't inherited.

David Hammen
  • 32,454
  • 9
  • 60
  • 108