2016-05-03 14 views
2

Ich versuche, einen Alias ​​für eine Vorlage zu erstellen, anstatt einen Typ und ich kann die Syntax nicht finden, um es zu tun. Unten ist ein Beispiel, das mein Problem zeigt. Meine Vermutung ist, dass dies nur etwas ist, das nicht gemacht werden kann, aber ich hoffe, dass jemand mir das Gegenteil beweisen kann. Wenn es nicht möglich ist, gibt es einen Grund dafür, dass es keinen Sinn macht, oder wird es einfach nicht implementiert?C++ Alias ​​zu Vorlage?

template <class S> 
class Down; 

template <class S> 
class Up { 
    template <class S1> 
    using Opposite = Down<S1>; 
}; 

template <class S> 
class Down { 
    template <class S1> 
    using Opposite = Up<S1>; 
}; 

template <template <typename> class Direction> 
void oneDirection() { 
    //Call another function here that uses the template argument as a template 
} 

template <template <typename> class Direction> 
void bothDirections() { 
    oneDirection<Direction>(); 
    oneDirection<Direction::Opposite>(); //This doesn't compile 
} 

int main() { 
    bothDirections<Up>(); 
} 
+0

Sie vermissen 'typename' in der Zeile, die Sie als nicht kompilierend markiert haben. – KyleKnoepfel

+0

@KyleKnoepfel Wie geschrieben, ist "Opposite" auch eine Vorlage, die ein Template-Argument benötigt, daher kann das Problem durch das Hinzufügen von 'type' nicht behoben werden. –

Antwort

3

In Direction::Opposite, Direction:: ist ein verschachtelten-name-specifier, und es kann in der Tat nicht eine Klassenvorlage bezeichnen (Sie müssen ihm die gewünschte Vorlage Argument geben, um es eine Template-Spezialisierung) .

Ich denke, ein Grund, diese Form nicht zuzulassen, ist, dass Klassenvorlagen teilweise oder explizit Spezialisierungen haben können, die verschiedene Mitglieder von der primären Vorlage zur Verfügung stellen können, so dass der Compiler mit einer bestimmten Spezialisierung arbeiten muss Was ist da drin?

Sie können dieses Problem umgehen, indem Züge mit den beiden Vorlagen zu verknüpfen: im Auge

template<class> class Up { }; 
template<class> class Down { }; 

template<template<class> class Direction> struct Direction_traits; 

template<> struct Direction_traits<Up> 
{ 
    template<class S1> using Opposite = Down<S1>; 
}; 

template<> struct Direction_traits<Down> 
{ 
    template<class S1> using Opposite = Up<S1>; 
}; 

template<template<class> class Direction> 
void oneDirection() { 
    //Do something here 
} 

template<template<class> class Direction> 
void bothDirections() { 
    oneDirection<Direction>(); 
    oneDirection<Direction_traits<Direction>::template Opposite>(); 
} 

int main() { 
    bothDirections<Up>(); 
} 

jedoch behalten, dass Direction_traits<Up>::Opposite nicht die gleiche Vorlage wie Down ist, zumindest noch nicht - die Sprachregeln ändern in der Zukunft, mehr Details in this answer und seine Kommentare.

Dies kann zu Problemen führen, wenn Sie von oneDirection<Direction_traits<Up>::Opposite> mit Hilfe der Merkmale zu Up zurückkehren möchten - es wird keine Merkmalspezialisierung für die Aliasvorlage definiert. Die Dinge müssten etwas komplizierter werden, um eine solche Verwendung zu ermöglichen; Eine mögliche Lösung wird in der oben zitierten Antwort skizziert.