模板专业化enable_if

时间:2019-05-21 06:13:03

标签: c++ templates override enable-if

我正在尝试以这种方式专门化模板:

class PropertyBase
{
public:
    SfPropertyBase(string name)
    {
        Name = name;
    }

    virtual ~SfPropertyBase() {}

    string Name;

    virtual bool FromString(Object* obj, string str) = 0;

};


template< typename T>
class Property : public SfPropertyBase
{
public:
    Property(string name) : SfPropertyBase(name)
    {
        //specific to Property stuff
    }



    template<typename U = T>
    typename std::enable_if<(std::is_class<U>::value && std::is_pointer<U>::value), bool>::type
    FromString(Object* obj, string str)
    {
        //do something
        return true;
    }

    template<typename U = T>
    typename std::enable_if<!std::is_class<U>::value || !std::is_pointer<U>::value), bool>::type
    FromString(Object* obj, string str)
    {
        //do something
        return true;
    }
}

然后,当我尝试初始化此类的实例时:

 auto prop = new Property<int>("IntProperty");

我得到invalid new-expression of abstract class type Property<int>。我知道PropertyBase中有一个抽象函数,但是我同时提供了Property的两个专业化,其中T是一个类,而不是。

怎么回事以及如何解决?

注意:如果T是类/指针以及所有其他情况,我想实现的是FromString的专业化。

2 个答案:

答案 0 :(得分:5)

FromString中的Property都是函数模板,它们不能覆盖基类的非模板virtual函数。 (实际上,功能模板不能为virtual functions。)

您可以在FromString中添加另一个非模板Property;并且您可以使用关键字orverride来确保覆盖。例如

bool FromString(Object* obj, string str) override {
    return FromString<>(obj, str);
}

LIVE

答案 1 :(得分:4)

功能模板不能用作非模板虚拟功能的替代程序。函数模板不是函数,它是在调用时按需创建函数的秘诀。

代码必须直接在派生类对象上调用FromString,SFINAE才能运行。如果要基于模板参数类型提供其他替代程序,则一种方法是通过中间基数。

template<typename T, typename = void>
struct FromStringProvider;

template<typename T>
struct FromStringProvider<T, typename std::enable_if<(std::is_class<U>::value && std::is_pointer<U>::value)>::type> : SfPropertyBase {
    bool FromString(Object* obj, string str) override
    {
        //do something
        return true;
    }
};

如果您需要访问派生类,则可以使用基于CRTP的方法。只需将派生类作为附加参数传递,并依靠其静态接口访问所需的部分即可。

如果您具有在相同条件下都具有的虚函数集,则这种替代方法特别有用。