Devolus
Devolus

Reputation: 22074

Overriding a virtual method based on template type sign

I'm trying to override a virtual method based on the members signedness, but somehow I don't get it right.

I'm using Visual Studio 2010 which doesn't support full C++11 but also in gcc it doesn't compile.

#ifndef SIGNED_TEMPLATE_H_
#define SIGNED_TEMPLATE_H_

#include <type_traits>
#include <iostream>

class Base
{
public:
    Base(void) {}
    virtual ~Base(void) {}

    virtual bool toValue(int *p) = 0;

    void Signed(bool bSigned) { mSigned = bSigned; }
    bool Signed(void) const { return mSigned; }

private:
    bool mSigned;
};

template<typename T>
class ColumnDef : public Base
{
public:
    ColumnDef(void) {}

    template<typename T,
    typename = std::enable_if<std::is_signed<T>::value>>
    bool toValue(int *p) override
    {
        std::cout << "Signed" << std::endl;

        return true;
    }

    template<typename T,
    typename = std::enable_if<std::is_unsigned<T>::value>>
    bool toValue(int *p) override
    {
        std::cout << "Unsigned" << std::endl;

        return true;
    }
};


#endif /* SIGNED_TEMPLATE_H_ */

Upvotes: 0

Views: 150

Answers (2)

Adrien Descamps
Adrien Descamps

Reputation: 690

You can't mix dynamic and static polymorphism, virtual functions can not be template.

The answer of Jarod42 is probably simpler, but just to demonstrate how you could use enable_if in this case:

class ColumnDef : public Base
{
public:
    ColumnDef(void) {}

    bool toValue(int *p)override
    {
        return toValueImpl<T>(p);
    }
private:
    template<typename T1>
    typename std::enable_if<std::is_signed<T1>::value,bool>::type toValueImpl(int *p)
    {
        std::cout << "Signed" << std::endl;
        return true;
    }

    template<typename T1>
    typename std::enable_if<std::is_unsigned<T1>::value,bool>::type toValueImpl(int *p)
    {
        std::cout << "Unsigned" << std::endl;
        return true;
    }
};

Upvotes: 1

Jarod42
Jarod42

Reputation: 217085

Your override is wrong...
You have to forward your call, something like:

template<typename T>
class ColumnDef : public Base
{
public:
    ColumnDef() {}

    bool toValue(int *p) override
    {
        return toValueImpl(p, std::is_unsigned<T>{});
    }

private:
    bool toValueImpl(int *p, std::true_type)
    {
        std::cout << "Signed" << std::endl;

        return true;
    }

    bool toValueImpl(int *p, std::false_type)
    {
        std::cout << "Unsigned" << std::endl;

        return true;
    }
};

Upvotes: 1

Related Questions