模板专业启用eNable_if

Template specialization enable_if

本文关键字:eNable if 启用      更新时间:2023-10-16

我试图以这种方式专业化模板:

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

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

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

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

live

一个函数模板不能用作非模板虚拟函数的效率。函数模板不是函数,它是呼叫时创建功能按需创建功能的食谱。

代码必须直接在派生类对象上调用FromString才能使Sfinae工作。如果您想根据模板参数类型提供不同的Overrider,一种方法是通过中间基础进行。

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的方法。只需将派生类作为额外的参数传递,然后依靠其静态接口来访问所需的零件。

如果您具有相同条件下的虚拟功能集,则这种替代方法特别有用。