fatehmtd
fatehmtd

Reputation: 43

Problems when overriding a method from a templated base class

In a class derived from a base templated class, I override a method createType(). When I try to access createType(int) of the derived class, the compiler says that it does not exist. Why?

template <class T>
class BaseClass
{
public:
    virtual T createType(){ return T(); }
    virtual T createType(int){ return T(); }
};

class Point
{
public:
    float x, y;
};

class PointFactory : public BaseClass<Point>
{
public:
    virtual Point createType() { return BaseClass::createType(); }
};

int main()
{
    PointFactory pf;
    auto p = pf.createType(5); // error here
    return 0;
}

The error I get is

error C2660: 'PointFactory::createType' : function does not take 1 arguments

Upvotes: 1

Views: 63

Answers (3)

Toby Speight
Toby Speight

Reputation: 30992

It may be clearer to examine the error reported by g++:

g++ -std=c++11 -g -Wall -Wextra -Wwrite-strings    -c -o 36315450.o 36315450.cpp
36315450.cpp: In function ‘int main()’:
36315450.cpp:24:29: error: no matching function for call to ‘PointFactory::createType(int)’
     auto p = pf.createType(5); // error here
                             ^
36315450.cpp:24:29: note: candidate is:
36315450.cpp:18:19: note: virtual Point PointFactory::createType()
     virtual Point createType() { return BaseClass::createType(); }
                   ^
36315450.cpp:18:19: note:   candidate expects 0 arguments, 1 provided
make: *** [36315450.o] Error 1

Because you override createType(), then createType(int) is shadowed. It will not be accessible unless you re-implement it in your derived class, perhaps using using:

class PointFactory : public BaseClass<Point>
{
public:
    virtual Point createType() { return Point(0,0); }
    using BaseClass<Point>::createType;
};

I've made the overriding createType() do something other than pass through to the base class, as otherwise it would be redundant here!

Upvotes: 0

Jarod42
Jarod42

Reputation: 218343

virtual Point PointFactory::createType() hides the base overloads.

You may add using BaseClass<Point>::createType; to fix that:

class PointFactory : public BaseClass<Point>
{
public:
    using BaseClass<Point>::createType; // unhide overloads

    Point createType() override { return BaseClass::createType(); }
};

Upvotes: 7

Some programmer dude
Some programmer dude

Reputation: 409482

Besides the overriding, you have two other problems:

  1. You call the child-class function with an argument, but the child-class has no member function with that name that takes an integer argument.

  2. return T;? If T was e.g. int then that would be return int;, how would you expect that to work? That will cause the functions in the base class not exist, and could give you a similar error to what you ask about once you override the function.

Upvotes: 0

Related Questions