我有一个类的模板(称其为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作为超类硬编码),一切都正常工作。然而,一旦我用注释掉的一行替换类定义,就会收到以下错误消息:
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
不是一个模板(如果我只是在结构体中硬编码一个类型),那么一切都能正常工作。
using cls = typename std::conditional<std::is_floating_point<T>::value, A, B>::type;
,但是std::conditional_t
看起来更好。+1 - NathanOliver