重写基于模板类型符号的虚拟方法

Overriding a virtual method based on template type sign

本文关键字:虚拟 方法 符号 类型 于模板 重写      更新时间:2023-10-16

我正试图基于成员的签名性来覆盖一个虚拟方法,但不知怎么的,我做得不对。

我使用的是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_ */

您的覆盖是错误的
你必须转发你的电话,类似于:

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

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

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