模板专业化 enable_if

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

然后,当我尝试初始化这个 class 的实例时:

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

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

这是怎么回事,如何解决?

注意:我想要实现的是专门化 FromString 如果 T 是 class/pointer 和所有其他情况。

Property中的FromString都是函数模板,不能覆盖的non-templatevirtual函数基地class。 (实际上函数模板不能是virtual functions)。

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

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

LIVE

函数模板不能用作 non-template 虚函数的重写。函数模板不是函数,它是在进行调用时按需创建函数的配方。

为了使 SFINAE 正常工作,代码必须直接在派生的 class 对象上调用 FromString。如果您想根据模板参数类型提供不同的覆盖程序,一种方法是通过中间基础。

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

如果您需要访问派生 class,则可以使用基于 CRTP 的方法。只需将派生 class 作为额外参数传递,并依赖其静态接口来访问您需要的部分。

如果您有多组虚函数,并且都在相同的条件下,这种替代方法特别有用。