Wenn CRTP innerhalb einer Vorlage verwendet wird (oder allgemein, wenn ein Vorlagenparameter als Basisklassenvorlagenargument übergeben wird), ist es dann nicht möglich, die Mitgliedsvorlagen der Basis in einer using
Deklaration zu benennen?Deklaration für typabhängigen Vorlagennamen
template< typename d >
struct base {
template<typename>
struct ct {};
template<typename>
void ft() {}
};
template< typename x >
struct derived : base< derived<x> > {
using derived::base::template ct; // doesn't work
using derived::base::ft; // works but can't be used in a template-id
};
Es scheint mir, dass dies ein Loch in der Sprache ist, einfach weil die mit Deklaration Grammatik Produktion keine qualifizierte Nummer nicht übernehmen.
using-declaration:
using typename(opt) nested-name-specifier unqualified-id ; // have this
using :: unqualified-id ;
unqualified-id:
identifier
operator-function-id
conversion-function-id
literal-operator-id
~ class-name
~ decltype-specifier
template-id
qualified-id:
nested-name-specifier template(opt) unqualified-id // want this
:: identifier
:: operator-function-id
:: literal-operator-id
:: template-id
Wenn die einzige Regel using-declaration: using typename(opt) qualified-id
, würden die einzigen Folgen
- sein
:: conversion-function-id
auszuschließen,:: ~ class-name
und:: ~ decltype-specifier template-id
, die keinen semantischen Sinn machen, - ermöglicht
:: template-id
die bereits verboten ist ausdrücklich 7.3.3/5 und - erlaubt das
template
Schlüsselwort, das bereits ausreichende Spezifikation hat, um das Loch zu patchen.
Ist diese Analyse korrekt?
Da die neue Grammatik zulässig ist, sollte eine Deklaration mit typename
eine Klassenvorlage oder Aliasvorlage importieren, und eine ohne typename
sollte eine Funktion oder Variablenvorlage in den aktuellen Bereich importieren.
using typename derived::base::template ct;
using derived::base::ft;
Dies könnte einige zusätzliche Spezifikationen erfordern. Auch der aktuelle Status quo scheint zu sein, dass abhängige Template-Namen immer mehrdeutige Art haben (nicht Template-IDs), so dass es nicht klar ist, dass typename
überhaupt zu ct
gehört.
Eine interessante Analyse. Ich bin gespannt, wo du das so gebrauchen würdest, dass das identifizierte "Loch" hemmen würde. I.e. Was ist eine Anwendung in der realen Welt, in der dies die Blockade ist, die dazu führt, dass Sie zurücktreten und die Architektur des Programms neu überdenken müssen? – WhozCraig
@WhozCraig Dies wird jedes Mal angezeigt, wenn Sie CRTP aus einer Vorlage verwenden. Die Basisklasse bietet eine Schnittstelle, für die Sie bei jeder Verwendung 'this -> * template' oder' base :: template' sagen müssen. – Potatoswatter
Ok, ich denke, ich verstehe es. Dieser spezielle Fall bezieht sich auf die Verwendung einer Klausel, die das Leben erleichtert, aber anscheinend nicht erlaubt ist. Gutes Beispiel. Vielen Dank. – WhozCraig