I have a base class with a virtual function:
class Base
{
public:
  virtual void Function();
};
void Base::Function()
{
  cout << "default version" << endl;
}
and a derived template class:
template <class T> class Derived : public Base
{
public:
  virtual void Function();
};
Is there a way to make Function() be taken from the base class for all types, except some chosen ones? So what I want is to be able to define an overriden Function() for, say, int and long:
void Derived<int>::Function()
{
  cout << "overriden version 1" << endl;
}
void Derived<long>::Function()
{
  cout << "overriden version 2" << endl;
}
and to have the default version of Function() for all other types, without explicit definition of Function() for them, so the output of
int main ()
{
  Derived<int> derivedInt;
  derivedInt.Function();
  Derived<long> derivedLong;
  derivedLong.Function();
  Derived<double> derivedDouble;
  derivedDouble.Function();
}
would be
overriden version 1
overriden version 2
default version
Is it possible?
There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.
You may overload a function template either by a non-template function or by another function template. The function call f(1, 2) could match the argument types of both the template function and the non-template function.
A template function can be overloaded either by a non-template function or using an ordinary function template.
A C++ template is a powerful feature added to C++. It allows you to define the generic classes and generic functions and thus provides support for generic programming. Generic programming is a technique where generic types are used as parameters in algorithms so that they can work for a variety of data types.
Member functions of class templates are in fact function templates, so you can specialize them:
template <typename T> class Foo
{
    void Function();
};
template <typename T> void Foo::Function() { /* ... */ }
template <> void Foo<int>::Function() { /* ... */ }
                        Yes, by specializing Derived.
Base)Derived to overrideSimple scheme, but it works.
First solution (use of the typeid operator): 
#include <iostream>
#include <typeinfo>
using namespace std;
class Base
{
public:
    virtual void Function();
};
void Base::Function()
{
    cout << "default version\n";
}
template<typename T>
class Derived : Base
{
public:
    virtual void Function();
};
template<typename T>
void Derived<T>::Function()
{
    if(typeid(T) == typeid(int)) // check if T is an int
    {
        cout << "overriden version 1\n";
    }
    else if(typeid(T) == typeid(long)) // check if T is a long int
    {
        cout << "overriden version 2\n";
    }
    else // if T is neither an int nor a long
    {
        Base::Function(); // call default version
    }
}
int main()
{
    Derived<int> di;
    Derived<long> dl;
    Derived<float> df;
    di.Function();
    dl.Function();
    df.Function();
    return 0;
}
I use the typeid operator to check if T is either an int or a long int, and if it is, I print "overriden version [number]". If it is not, I call Base::Function(), which will print "default version"
Note: to use the typeid operator you need to include the header file typeinfo  
Second solution (using template specializations):
// class declarations as before
template<typename T>
void Derived<T>::Function()
{
    Base::Function(); // call default version
}
template<>
void Derived<int>::Function()
{
    cout << "overriden version 1\n";
}
template<>
void Derived<long>::Function()
{
    cout << "overriden version 2\n";
}
int main()
{
    Derived<int> di;
    Derived<long> dl;
    Derived<float> df;
    di.Function();
    dl.Function();
    df.Function();
    return 0;
}
Here, I solve your problem with template specializations. If T is either an int or a long int, I call the specialized versions. Else, i call the general version, which is equivalent to Base::Function().
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