我有一个类的模板(我们称之为 A),它应该是其他类(B 或 C)之一的子类,具体取决于我的自定义特征结构中的编译时间条件。我附上了一个重现行为的片段。
#include <type_traits>
template<typename T>
class cls_template {
public:
using method_arg_type = T;
virtual void method(method_arg_type) = 0;
};
using A = cls_template<float>;
using B = cls_template<int>;
template<typename T>
struct traits {
using cls = std::conditional<std::is_floating_point<T>::value, A, B>;
};
//class C : public traits<float>::cls {
class C : public A {
public:
virtual void method(method_arg_type arg) {};
};
int main() {
A *a = new C();
}
如果我这样保留(将 A 硬编码为父类(super class)),则一切正常。但是,一旦我用注释掉的行替换了类定义,我就会收到以下错误消息:
test.cpp:21:27: error: unknown type name 'method_arg_type'
virtual void method(method_arg_type arg) {};
^
test.cpp:25:10: error: cannot initialize a variable of type 'A *'
(aka 'cls_template<float> *') with an rvalue of type 'C *'
A *a = new C();
^ ~~~~~~~
为什么
method_arg_type
不再定义?为什么 C
不再被识别为 A
的子类?我发现如果 traits
不是模板(如果我只是将类型硬编码到结构中),则一切正常。 最佳答案
您正在尝试从 traits<float>::cls
类型的 std::conditional<std::is_floating_point<T>::value, A, B>
派生。它既不是 A
也不是 B
,它是 conditional
模板的特化。要么从它的 ::type
派生,它会按你的预期工作,要么使用 conditional_t
(C++14)。
class C : public traits<float>::cls::type { // ok
^^^^^^
public:
virtual void method(method_arg_type arg) {};
};
demo
template<typename T>
struct traits {
using cls = std::conditional_t<std::is_floating_point<T>::value, A, B>;
^^
// above is C++14, in C++11 you'd have to write
// using cls = typename std::conditional<std::is_floating_point<T>::value, A, B>::type;
};
class C : public traits<float>::cls { // also ok
public:
virtual void method(method_arg_type arg) {};
};
demo
关于c++ - 如何对由特征选择的父类(super class)进行子类化?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40535707/