谁能解释为什么下面的代码在 Visual Studio 2015 C++ 中给出错误“error C2259: 'PropertyValue': cannot instantiate abstract class”?
编译器是否无法识别派生类 PropertyValue
中的条件指定函数 ConvertToDevice()
具有相同的签名?
非常感谢,
约翰
#include <type_traits>
#include <typeinfo>
class BasePropertyValue
{
public:
virtual int ConvertToDevice(void** ptrdObject) = 0;
};
template<typename T> class PropertyValue : public BasePropertyValue
{
public:
T value;
PropertyValue(T val)
{
value = val;
}
template<class Q = T>
typename std::enable_if<!std::is_pointer<Q>::value, int>::type ConvertToDevice(void** ptrdObject)
{
return 1;
}
template<class Q = T>
typename std::enable_if<std::is_pointer<Q>::value, int>::type ConvertToDevice(void** ptrdObject)
{
return 2;
}
};
void main()
{
PropertyValue<double>* prop1 = new PropertyValue<double>(20);
prop1->ConvertToDevice(nullptr);
double x = 20;
PropertyValue<double*>* prop2 = new PropertyValue<double*>(&x);
prop2->ConvertToDevice(nullptr);
return;
}
[edit] 由于条件特征方面的原因,这不是一个重复的问题。
最佳答案
首先,您将要覆盖的函数声明为模板。你不能有模板虚函数。就这么简单。
对于解决方案,您制作这些模板似乎只是为了能够在两种实现之间切换。一个简单的解决方案是实现一个覆盖的单个函数,然后在其中调用一个模板函数:
template<typename T>
struct PropertyValue : BasePropertyValue {
T value;
// simpler constructor
PropertyValue(T val) : value{std::move(val)} {}
// the override keyword is important
int ConvertToDevice(void** ptrdObject) override
{
return ConvertToDeviceImpl(ptrdobject);
}
private:
template<class Q = T>
typename std::enable_if<!std::is_pointer<Q>::value, int>::type
ConvertToDeviceImpl(void** ptrdObject)
{
return 1;
}
template<class Q = T>
typename std::enable_if<std::is_pointer<Q>::value, int>::type
ConvertToDeviceImpl(void** ptrdObject)
{
return 2;
}
};
关于c++ - 在派生模板类中使用条件类型特征覆盖基类中的虚拟方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46163972/