2015-03-12 31 views
13

Betrachten Sie den folgenden Code ein:Ist es möglich, einen Vorlagenalias zu erstellen?

template< template< typename ... > class ... Ts > 
struct unite 
{ 
    template< typename ... T > 
    struct type 
     : Ts< T ... > ... 
    { }; 
}; 

// This does not work as ::type does not name a type, but a template: 

// template< template< typename ... > class ... Ts > 
// using unite_t = typename unite< Ts ... >::type; 

template<typename> struct debug_none {}; 
template<typename> struct debug_cout {}; 

template< typename ... > struct raise_demangled {}; 
template< typename ... > struct raise_specialized {}; 

template< typename, typename = int > struct match_default {}; 

template< template< typename ... > class Control > 
void f() 
{} 

int main() 
{ 
    f< unite< debug_none, raise_demangled, match_default >::type >(); 

    // Is there any way to create something like unite_t which works like this: 

    // f< unite_t< debug_none, raise_demangled, match_default > >(); 
} 

Live example

Frage: Gibt es eine Möglichkeit, eine Art von "Vorlage alias" ähnlich einem Typ alias zu erstellen? (siehe obiges Beispiel)

+1

Also, Frage: Ich erinnerte mich, als ich schrieb, dass ich diese genaue Frage zuvor gestellt habe. Sollte ich meine http://stackoverflow.com/questions/17356487/äquivalent-of-using-aliases-for-templates als ein Duplikat von diesem schließen? Oder umgekehrt? :) – Yakk

+1

@Yakk Obwohl Ihre Frage ziemlich ähnlich ist und in der gleichen Gegend, ich glaube nicht, dass es wirklich ein Duplikat ist, wie Sie versucht haben, das Schlüsselwort 'template' an einem anderen Ort loszuwerden. Wenn eine Lösung für einen * existiert *, * könnte * das andere Problem ebenfalls lösen - aber es scheint, dass es keine Lösung gibt. –

Antwort

5

Nein, das geht nicht.

using kann einen Typ oder eine Variable "zurückgeben". Es kann keine template "zurückgeben". Es gibt keine ähnlichen Mechanismen an anderer Stelle.

Sie etwas vage nützlich, indem sie die Konvention tun können, dass alle Vorlagen nicht Vorlagen sind, sondern Klassen mit template<?>using apply=?; Alias ​​in ihnen (und wenn wir schon dabei sind, Konstanten sind std::integral_constants<T,?> und Zeiger sind pointer_constant<T*,?>).

Jetzt ist alles eine Klasse. template s werden nur Arten von Klassen (mit ::apply<?...>

ein Bündel von Typen zu einer solchen Vorlage anwenden würde getan werden über:.

template<class Z, class...Ts> 
using apply_t = Z::template apply<Ts...>; 

So mit einem „native“ Vorlage Z, Sie‘ d Z<Ts...> zu tun. Mit diesen „indirekten“ Vorlagen, würden Sie apply_t<Z, Ts...> tun.

Mit dieser Konvention eine Vorlage using alias eine indirekte Vorlage zurückkehren kann. Wenn der Rest des Codes der conven folgt Wenn Sie immer eine apply_t aufrufen, um eine Vorlage anzuwenden, und Sie alle anderen Vorlagen, die Sie schreiben, indirekt machen, sind wir fertig.

Das ist hässlich.

+0

Gibt es einen Vorschlag, dies zu beheben? – Brian

+0

@Brian nicht, dass ich weiß. Die Notwendigkeit, solche Aliase zu haben, ist fraglich, da nur relativ fortgeschrittene Verwendung von C++ es erfordert, also hat sich vielleicht niemand gestört. – Yakk

+0

Danke für deine Antwort, ich werde es wohl bald als "akzeptiert" bezeichnen - das "Nein, du kannst nicht" -Teil :) Leider kann die vorgeschlagene Alternative/Umgehung in meinem Fall nicht wirklich genutzt werden, da es das machen würde Schnittstelle (die für den Benutzer sichtbar ist) noch komplizierter/hässlicher. Ich erwäge tatsächlich, diese Idee fallen zu lassen, anstatt die Benutzer zu verwirren. –

Verwandte Themen