2016-11-10 2 views
3

Ich habe eine Vorlage einer Klasse (nennen wir es A), die eine der anderen Klassen (B oder C) ableiten sollte, abhängig von einer bedingten Kompilierungszeit in meiner benutzerdefinierten Trait-Struktur. Ich füge einen Ausschnitt an, der das Verhalten reproduziert.Wie man eine Superklasse ableitet, die durch Eigenschaften ausgewählt wird?

Wenn ich es so lasse (Hardcoding A als Superklasse), alles funktioniert gut. Sobald jedoch ersetze ich die Klassendefinition mit einer kommentierten out Zeilen ich folgende Fehlermeldungen bin immer:

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(); 
    ^ ~~~~~~~ 

Warum ist method_arg_type nicht mehr definiert? Warum wird C nicht länger als Unterklasse von A erkannt? Ich habe herausgefunden, dass, wenn traits keine Vorlage sind (wenn ich nur einen Typ in die Struktur fest codiere), alles funktioniert gut.

Antwort

4

Sie versuchen, von traits<float>::cls abzuleiten, die vom Typ std::conditional<std::is_floating_point<T>::value, A, B> ist. Es ist weder A noch B, es ist eine Spezialisierung der conditional Vorlage. Entweder leiten Sie von ::type davon, die wie erwartet funktionieren wird, oder conditional_t (C++ 14) verwenden.

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

+1

Zusätzlich 'mit cls = Typname std :: bedingte :: Wert, A, B> :: Typ;' kann sein verwendet, aber 'std :: conditional_t' sieht viel besser aus. +1 – NathanOliver

+0

Ugh, ja du hast den Typ im Beispiel, aber leider ist es nicht das Problem, das ich in meinem echten Code habe. Ich werde versuchen, einen weiteren Ausschnitt zu isolieren. – wesolyromek

Verwandte Themen