2009-09-18 15 views
5

ein Template-Parameter deklariert verwenden können, in einem anderen Template-Parameter verwendet werden, die es auf diese Weise folgt:Wie ein Template-Parameter in einem anderen Template-Parameter vor

template<typename T, T N> 
struct s 
{ 
}; 

Aber ist es möglich, referenzieren „T“, wenn es nach "N" deklariert?

funktioniert das nicht:

template<T N, typename T> 
struct s 
{ 
}; 

Können wir die Compiler durch vorherige Deklarierung „T“ oder irgendetwas anderes zu tun, helfen?

Danke von Voraus.

EDIT: als die ersten zwei Antworten fragen "Warum bist du bereit, das zu tun?" Ich werde das Ziel erklären:

Ich möchte den Compiler den Typ "T" ableiten, um die Verwendung von Vorlagenklassen zu erleichtern.

Zum Beispiel:

template<typename T, T A, T B> 
struct sum 
{ 
    static T const value = A + B; 
}; 

Diese Vorlage kann auf diese Weise verwendet werden:

sum<int, 1, 2>::value 

Aber es wäre besser, wenn es auf diese Weise verwendet werden könnte:

sum<1, 2>::value 

Technisch Es sollte möglich sein, weil der Compiler die Typen "1" und "2" kennt: "int", und tatsächlich verwendet er diese inf um die beste Überladung für eine Funktion zu finden. So von der Vorlage auf diese Weise erklärt:

template<T A, T B, typename T> 
struct sum 
{ 
    static T const value = A + B; 
}; 

der Compiler seine Fähigkeit zu nutzen, um die letzten Parameter von den Informationen durch die erste und die zweiten zur Verfügung gestellt zu schließen, und dann die beste Vorlage finden zu instanziiert.

Antwort

6

Wie andere sagen - Nein dies nicht möglich ist, kann der Compiler nicht die Art von T aus dem nicht-Typ Vorlage Argumente (im Fall von Funktionen ableiten, folgert sie Typen aus der Funktion Argumente):

14.8.2.4/12:

ein Typ Argument Vorlage nicht vom Typ eines nicht-Typ Template-Argument abgeleitet werden kann.

In jedem Fall wird sowieso kein Abzug für die Argumente einer Klassenvorlage vorgenommen. Ein Beispiel für eine Funktionsvorlage könnte

sein
template<int> struct having_int { }; 
template<typename T, T i> void f(having_int<i>); 
int main() { having_int<0> h; f(h); } 

In diesem Fall T nicht als int abgeleitet werden - man muss es explizit angeben.

+0

Danke für die Antwort: Wenn die Norm nein sagt, ist es nicht. Die Frage ist jetzt: Warum dieses begrenzte Verhalten, während es scheint, dass diese Ableitung möglich ist? Haben Sie einige Beispiele, die diese Entscheidung rechtfertigen? Danke. – Pragmateek

+0

Weil Template-Metaprogrammierung niemals expressiv sein sollte? :) Interessante Frage, obwohl. Vielleicht sollten Sie überprüfen, ob dies vorgeschlagen wurde, oder diesen Vorschlag für C++ 1x machen. – UncleBens

0

Sie können nicht. Ich verstehe nicht, warum Sie es auch tun.

0

Unten ist Quatsch, da ich deine Frage nicht richtig gelesen habe.

In der Tat sehe ich keinen Sinn darin, was Sie auch erreichen wollen.

#include <iostream> 

template<typename T, T N> 
struct s 
{ 
    T size() { return N; } 
}; 


int main() 
{ 
    s<int, 4> x; 
    std::cout << x.size()<< '\n'; 

    //s<float, 3.14> f; //this doesn't compile 
} 

Dies kompiliert für mich mit GCC und Comeau Online.

Ich denke, das Problem ist mit der Art von T, die Sie versuchen zu verwenden. Nicht typisierte Vorlagenargumente unterstützen nur ganzzahlige Typen und dann Zeiger auf Objekte mit externer Verknüpfung (oder etwas ähnliches und vielleicht ein paar andere sehr begrenzte Dinge).

Verwandte Themen