“template polymorphism” when calling function for templated parameter of base type, with derived type?

前端 未结 2 1555
抹茶落季
抹茶落季 2021-01-20 15:42

I\'ve got a template class:

template 
class TemplateClass
{
   //irrelevant what this class does
}

And two classes, one base

相关标签:
2条回答
  • 2021-01-20 16:07

    It is simple to solve this if you are not opposed to a more general situation:

    I would simply add a template parameter to your DoSomething function:

    template<class T>
    void DoSomething(const TemplateClass<T *> &tc)
    {
    }
    

    Of course, this doesn't allow you to directly constrain the parameter T to being a subclass of Base. But it will allow you to not write several overloads of DoSomething.

    Edit

    If your TemplateClass was intended to wrap a value of type T, then there may be a way to constrain to parameter for DoSomething.

    Suppose TemplateClass were declared something like

    template<class T>
    class TemplateClass
    {
    
    public:
    
        TemplateClass( T value )
        : Value(value)
        {
        }
    
        T Value;
    };
    

    Then DoSomething could be written as

    template<class T>
    void DoSomething( const TemplateClass<T *> &tc )
    {
        Base * b = tc.Value;
    }
    

    Now, during compilation, the line Base * b = tc.Value will only compile if T is set to a subclass of Base. Otherwise, it will fail due to an invalid conversion.

    Of course, this is a very simple example which may ignore some elements of good design. But the principle is there, and this is the only way I am currently aware of the produce such a constraint on a template parameter.

    0 讨论(0)
  • 2021-01-20 16:13

    Sadly, C++ does not support template covariance, so you cannot do that automatically. As a workaround, you could do something like this:

    template <typename T>
    void DoSomething(const TemplateClass<T*>& tc) {
        // in C++03, use BOOST_STATIC_ASSERT and boost::is_convertible
        static_assert(
            std::is_convertible<T*, Base*>::value,
            "Template argument must be convertible to Base*"
        );
    
        // ...
    }
    

    Demo on ideone.

    0 讨论(0)
提交回复
热议问题