2016-03-23 4 views
2

Ich möchte eine Template-Klasse mit Variadic Vorlage Template-Parameter von Nicht-Template-Klasse spezialisieren. Siehe unten.Kann ich einen variablen Template-Vorlagenparameter mit einer nicht-Template-Klasse spezialisieren?

// non-template base class 
class BaseNoneTemplate { 
public: 
    void print(void) { 
     std::cout << "BaseNoneTemplate" << std::endl; 
    } 
}; 

// template base class 
template <typename T> 
class BaseTemplate { 
public: 
    void print(void) { 
    std::cout << "BaseTemplate" << std::endl; 
    } 
}; 

// primary template class 
template <template <typename...> class T_Self, typename... T_Params> 
class VariadicTemplate : public T_Self<T_Params...> { 
public: 

    VariadicTemplate() = default; 
    virtual ~VariadicTemplate() = default; 

    void print(void) { 
     this->T_Self<T_Params...>::print(); 
    } 

}; 

// specialized class with a non-template class 
// ********** This specialized class makes an error: see the error message at the end of this question *********** 
template <> 
class VariadicTemplate<BaseNoneTemplate> : public BaseNoneTemplate { 
public: 

    VariadicTemplate() = default; 
    virtual ~VariadicTemplate() = default; 

    void print(void) { 
     this->BaseNoneTemplate::print(); 
    } 

}; 

// specialized class with an template class 
// ***** This class is an ok example ***** 
template <typename T_Value> 
class VariadicTemplate<BaseTemplate, T_Value> : public BaseTemplate<T_Value> { 
public: 

    VariadicTemplate() = default; 
    virtual ~VariadicTemplate() = default; 

    void print(void) { 
     this->BaseTemplate<T_Value>::print(); 
    } 

}; 

void test_variadic_template(void) { 
    VariadicTemplate<BaseNoneTemplate> non_template; 
    VariadicTemplate<BaseTemplate, int> an_template; 
    non_template.print(); 
    an_template.print(); 
} 

In dem obigen Code, konnte ich nicht eine Template-Klasse mit variadische Template-Template-Parametern von Nicht-Template-Klasse, BaseNoneTemplate spezialisiert. Kann jemand es mit Nicht-Template-Klasse spezialisieren?

Der Fehler durch Compiler wird wie folgt,

../template_template_variadic.hpp:44:40: error: type/value mismatch at argument 1 in template parameter list for ‘template<template<class ...> class T_Self, class ... T_Params> class VariadicTemplate’ class VariadicTemplate<BaseNoneTemplate> : public BaseNoneTemplate { 
            ^
../template_template_variadic.hpp:44:40: note: expected a class template, got ‘BaseNoneTemplate’ 

Thank you very much.

Antwort

1

Wie wäre es, eine weitere Verallgemeinerungsebene hinzuzufügen?

//... 
template <typename... Types> 
class VariadicTemplate; 

// primary template class 
template <template <typename...> class T_Self, typename... T_Params> 
class VariadicTemplate<T_Self<T_Params...>, T_Params...>: public T_Self<T_Params...> { 
//... 
}; 

//... 
void test_variadic_template(void) { 
    VariadicTemplate<BaseNoneTemplate> non_template; 
    VariadicTemplate<BaseTemplate<int>, int> an_template; 
    non_template.print(); 
    an_template.print(); 
} 

Ich habe Teile entfernt, die ich nicht geändert habe. Dieser Code kompiliert nicht auf MSVC2015, obwohl aus dem Grund unbekannt. Ich habe eine bug eingereicht, aber wenn Sie es verwenden, dann wird es Ihnen in nächster Zeit nicht helfen.


Diese Version funktioniert auf MSVC (neben prägnanter und sauber zu sein):

template <typename... Types> 
class VariadicTemplate; 
//.. 
template <template <typename...> class T_Self, typename... T_Params> 
class VariadicTemplate<T_Self<T_Params...>>: public T_Self<T_Params...> { 
//... 
} 
//... 
void test_variadic_template(void) { 
    VariadicTemplate<BaseNoneTemplate> non_template; 
    VariadicTemplate<BaseTemplate<int>> an_template; 
    non_template.print(); 
    an_template.print(); 
} 
+0

Danke, ixSci mir die Antwort zu geben. – mora

+0

@mora, wenn die Antwort Ihnen geholfen hat, bitte akzeptieren Sie es (ein Häkchen neben der Antwort) – ixSci

+0

Hallo, ixSci. Ich habe es vorher gedrückt und es wurde grün. Wie auch immer, vielleicht wurde es nicht akzeptiert. Ich drücke es nochmal. Ist es o.k? Oder wie kann ich überprüfen, ob es funktioniert? – mora

1

Wenn Ihr VariadicTemplatetemplate <typename...> class, typename... als Template-Argument erwartet, können Sie es nicht für Art spezialisiert.

Was Sie tun können, ist Typ zu erwarten und spezialisieren für bestimmten Typ oder (teilweise) spezialisieren für Typen, die aus Vorlagentypen kommen.

template <typename T> class VariadicTemplate; 

// Partial specialization 
template <template <typename...> class C, typename... Ts> 
class VariadicTemplate<C<Ts...>> : public C<Ts...> { 
public: 
    void print() { C<Ts...>::print(); }; 
    // or using C<Ts...>::print; 
}; 

// Full specialization 
template <> 
class VariadicTemplate<BaseNoneTemplate> : public BaseNoneTemplate { 
public: 
    void print() { BaseNoneTemplate::print(); }; 
    // or using BaseNoneTemplate::print; 
}; 

Demo

+0

Danke, Jarod42 für eine andere Lösung. Wenn ich eine Template-Klasse nur mit einem (Template-) Typ als Template-Augment erwarte, also VariadicTemplate , ist Ihre Lösung natürlicher als mein Code oben. Danke nochmal. – mora

Verwandte Themen