我正在尝试以这种方式专门化模板:
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
的专业化。
答案 0 :(得分:5)
FromString
中的Property
都是函数模板,它们不能覆盖基类的非模板virtual
函数。 (实际上,功能模板不能为virtual
functions。)
您可以在FromString
中添加另一个非模板Property
;并且您可以使用关键字orverride
来确保覆盖。例如
bool FromString(Object* obj, string str) override {
return FromString<>(obj, str);
}
答案 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的方法。只需将派生类作为附加参数传递,并依靠其静态接口访问所需的部分即可。
如果您具有在相同条件下都具有的虚函数集,则这种替代方法特别有用。