2015-12-29 40 views
5

Istnieją dwa przypadki, w których typedef wprowadza mnie w błąd, jeśli chodzi o extern template declaration i explicit template instantiation.przy użyciu polecenia typedef w szablonie i deklaracji szablonu zewnętrznego

Aby zilustrować dwa, zobacz poniżej 2 przykładowe fragmenty kodu.

Rozważmy następujący przykład (przypadek 1):

// suppose following code in some cpp file  
template <typename T> 
    struct example 
{ 
    T value; 
}; 

// valid typedefs 
typedef example<int> int_example; 
typedef example<std::string> string_example; 

// explicit instantiation using above typedefs 
template class int_example; // -> compile time error 
template class string_example; // -> compile time error 

// instead we need to use type names 
template class example<int>; // -> OK 
template class example<std::string>; // -> OK 

// QUESTION 1: Why does this work however? is this valid code? 
typedef std::string type_string; 
template class example<type_string>; 

Dlaczego template class example<type_string> praca z typedef? i dlaczego jest ważna, podczas gdy template class string_example nie jest?

Rozważmy następujący przykład (przypadek 2):

// suppose following code is in some header file 
template <typename T> 
struct example 
{ 
    T value; 
}; 

// valid typedefs 
typedef std::string type_string; 
typedef example<type_string> string_example; 

// Explicit instantiation declaration 
// QUESTION 2: Is this valid code? if not why not? 
extern template string_example; // -> at least this compiles, but is it OK? 

Jak przesłuchiwany w komentarzu powyżej, jest to ważne, aby używać typedef w extern template declaration, jak w powyższym przykładzie, i dlaczego to skompilować w przeciwieństwie do Case1 gdzie nie ma.

Czytałem o podobnych przypadkach, ale żadna nie daje szczegółowej odpowiedzi na powyższe 2 pytania. szczegółowe opracowanie jest bardzo doceniane!

Odpowiedz

2
template class int_example; 

nie jest legalny. Od C++ 11 Stanard:

14.7.2 Explicit instancji

2 Składnia wyraźnej instancji jest:

wyraźne-instancji:
extern opttemplatedeklaracja

Istnieją dwie formy jawnego tworzenia instancji: jawna definicja instancji i jawna deklaracja wystąpienia. Wyraźna deklaracja wystąpienia zaczyna się od słowa kluczowego extern.

3 Jeśli wyraźny instancji jest dla klasy lub członkiem klasy, opracowany TYPU specyfikator w deklaracjiobejmuje prosty szablon-id.

prosty szablon id jest zdefiniowana w sekcji A.12 Szablony jak:

prosty szablon-ID:
nazwa-szablonu<szablon Argument lista- opt>

int_example nie kwalifikuje się jako simple-template-id.
example<int> kwalifikuje się jako simple-template-id.

Jednak przez tą logiką,

extern template string_example; 

nie jest legalny albo. Nie wiem, jak to działa dla ciebie. Wystąpił następujący błąd podczas próby skompilowania takiej linii w g ++ 4.9.3.

socc.cc:15:31: error: expected unqualified-id before ‘;’ token 
extern template string_example; // -> compile time error 
+0

wiesz dlaczego 'szablon klasy przykładem ;' i 'extern przykład klasa szablon ;' działa (lub nie robi z GCC), używam btw MSVC-140 i to działa. Dzięki wielkie! – codekiddy

+0

'przykład ' kwalifikuje się jako * simple-template-id *. –

+0

dziękuję, zrobiłem kilka testów z GCC i są przypadki, w których g ++ wydaje niezdefiniowane odniesienia dla przypadków, takich jak 'przykład ' ale msvc kompiluje się dobrze, są też przypadki gdzie msvc daje ostrzeżenia, ale nie g ++, oczywiście te przypadki są ani opisane, ani dobrze zdefiniowane przez standard. – codekiddy