基于模板类型符号覆盖虚拟方法

时间:2015-11-19 18:41:48

标签: c++ templates

我试图根据会员签名来覆盖虚拟方法,但不知怎的,我没有做好。

我使用的是Visual Studio 2010,它不支持完整的C ++ 11,但是在gcc中它也不能编译。

#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_ */

2 个答案:

答案 0 :(得分:1)

您的覆盖错误...
你必须转发你的电话,例如:

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;
    }
};

答案 1 :(得分:1)

你不能混合动态和静态多态,虚函数不能是模板。

Jarod42的答案可能更简单,但只是为了演示如何在这种情况下使用enable_if:

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;
    }
};