2016-09-30 3 views
0

Beachten Sie Folgendes:öffentlicher Zugang von Vorlagen Wert

template<int T> 
class Test { 
public: 
    constexpr static int A = T; 
}; 

int main(int argsc, char** args) { 
    std::cout << Test<2>::T << std::endl; // Option 1 
    std::cout << Test<2>::A << std::endl; // Option 2 
} 

Warum funktioniert die Option 1 Kompilierung? Es scheint, dass die static constexpr A nur ein zusätzlicher Schritt ist. Ist T nicht öffentlich verfügbar?

Gibt es einen saubereren Weg, um T zu bekommen, als durch Erstellen eines öffentlich zugänglichen Mitglieds wie A oben?

+0

Sie können nicht auf die Vorlagenparameter außerhalb der Klasse zugreifen. – plasmacel

+0

@plasmacel - warum ist das wahr? Der Schritt zum Erstellen von "A" scheint unnötig. – Jack

+1

Sie können auch ein Merkmal erstellen, mit dem Vorlagenparameter abgerufen werden können. 'Vorlage TestTrait; Vorlage TestTrait > Struktur {constexpr statisch int Wert = N; }; ' – Jarod42

Antwort

2

Warum kompiliert Option 1 nicht?

Da ein Vorlagenparameter nur der Name eines Parameters ist. Sie sind sie umbenennen erlaubt, das heißt:

template <class T> struct X; 

// refers to same X 
template <class U> struct X { ... }; 

// still the same X 
template <class V> 
void X<V>::foo() { ... }; 

Aus dem gleichen Grund, dass Sie erlaubt sind Ihre Funktionsparameter unterschiedlich zwischen der Deklaration und Definition zu nennen. Wenn der Name des Vorlagenparameters automatisch in der Klassenvorlage angezeigt werden würde, müsste er auf Anhieb korrigiert werden.

Gibt es einen saubereren Weg, um bei T als durch die Schaffung eines öffentlich zugänglichen Mitglieds wie A oben zu bekommen?

Erstellen der öffentlich zugänglichen Mitglied ist in der Regel der Weg zu gehen. Alternativ können Sie ein externes Merkmal anlegen:

template <class T> struct X { using type = T; }; // internal 

template <class > struct get_type; 
template <class T> struct get_type<X<T>> { using type = T; }; // external 
+0

Funktioniert 'using type = T', wenn' type' kein Typ ist, sondern ein 'int'-Wert? – Jack

+0

@Jack Nein, Sie müssten 'static constexpr int value = T;' Ich verwende nur Typen, weil Typen typischer sind. – Barry

+0

Es muss erwähnt werden, dass die Funktion, mit der Sie die Parameter außerhalb der Klasse umbenennen können, die Funktion nicht ausschließt, um auf die Parameter über ihren ursprünglichen Namen zuzugreifen oder sie nach ihrem Index zu extrahieren. Es ist also eher eine Einschränkung des Standards. – plasmacel