我有一个类(我们称它为 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) {};
};
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) {};
};
关于c++ - 如何子类化由特征选择的父类(super class)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40535707/