2015-04-09 19 views
5

To pytanie może być dobrze odpowiedział jeden ale niestety nie wiem prawidłową terminologię, żeby go zapytać prawidłowo, więc ...C++ szablonu argument, który już jest „znany”

template <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> class __bit_iterator; 

Może ktoś wyjaśnić ostatni argument szablonu? Jedyną rzeczą, którą mogę wywnioskować, jest to, że jeśli parametr określony dla _Cp ma typ podrzędny __storage_type, wówczas wszelkie użycie _Cp :: __ storage_type w szablonie rozwiąże ten problem. Jeśli tak nie jest, oznacza to, że _Cp :: __ storage_type ma wartość 0? Wydaje mi się to bardzo perwersyjne (lub raczej błędne po odrobinie eksperymentów).

Objaśnienie dotyczy poprawnej terminologii i referencji w C++.

Dla zainteresowania, ten kod został pobrany z biblioteki libC++.

+1

Tylko dla rekordu: to wygląda jak kod biblioteki, nie używaj nazw zaczynających się od '_X' dla wielkich liter" X "lub mających podwójne podkreślenia w nazwie' __', ponieważ są one zarezerwowane. - całkowicie niezwiązane z twoim pytaniem :) –

+1

@ DavidRodríguez-dribeas Powiedział, że ten kod jest częścią 'libC++'. –

+0

@MateuszGrzejek: I Dawid powiedział "zupełnie niezwiązany z twoim pytaniem". Zostawia notę ​​doradczą. –

Odpowiedz

7

Klasa szablon __bit_iterator przyjmuje trzy argumenty:

  • klasa _Cp
  • logiczną _IsConst
  • obiekt typu _Cp::__storage_type (prawdopodobnie liczba całkowita), która jest podana żadna nazwa
    • to Argument jest opcjonalny i domyślnie przyjmuje wartość 0

Celem trzeciego argumentu (ponieważ jest bezimienny, a tym samym nie może być używany wewnątrz definicji __bit_iterator) wydaje się być jedynie wymagać, aby klasa _Cp ma typ użytkownika __storage_type, który jest kompatybilny z wyrażeniem 0 . Jeśli tak nie jest, ta instancja (z tym _Cp) nie może się skompilować.

+0

Dzięki. Brakowało mi elementu _Cp :: __ storage_type to nienazwany parametr. Dzięki tym informacjom pasuje do mojego zrozumienia szablonów (na szczęście!). Nie po raz pierwszy zostałem złapany przez anonimowe typy w C++! –

+0

Co to jest * typ członka *? Czy jest to definicja typu w klasie? Lub "członek typu", który nie ma większego sensu w tym kontekście. – luk32

+0

@ luk32: Tak, definicja typu w klasie. Może to być alias ('using',' typedef') lub zagnieżdżony UDT ('class',' struct'). Jest to typ członka, c.f. funkcja członka, zmienna składowa. –

1
template <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> 
class __bit_iterator; 

To wygląda jak zakaz typu szablonu argumentu (nie różni się od poprzedniego _IsConst argument), który jest inicjowane z 0, jeśli użytkownik nie przewidziane. Możliwym specjalizacja tego szablonu mogą być:

struct X { typedef int __storage_type; }; 
__bit_iterator<X, false> bi; 

To byłoby równoznaczne z:

__bit_iterator<X, false, X::__storage_type(0)> bi; 

który jest naprawdę odpowiednik (od X::__storage_type jest int) na adres:

__bit_iterator<X, false, 0> bi; 
3
template <class _Cp, bool _IsConst, typename _Cp::__storage_type = 0> 
class __bit_iterator; 

__bit_iterator to szablon klasy. Ten szablon przyjmuje trzy argumenty.

  1. _Cp, który jest typem.

  2. _IsConst, która jest wartością boolowską.

  3. Ostatni parametr jest nienazwany i jest wartością (podobnie jak _IsConst).Typ tego parametru to type/typedef zadeklarowany w _Cp i nazwany __storage_type.

Jeśli są mylone przez typename słowa kluczowego: typename jest a method for indicating that a dependent name is a type.

_Cp jest argumentem szablonu i może być dowolnego typu. Nawet typ, który nie zawiera niczego takiego jak __storage_type. Dlatego musimy powiedzieć kompilatorowi, że coś takiego powinno tam istnieć i jest typem/typedef. Jeśli to wymaganie nie zostanie spełnione, zostanie zgłoszony błąd podczas kompilacji.

+0

Dzięki. Myślę, że jest to nieco bardziej rygorystyczne wymaganie niż tylko wymaganie, aby _Cp miał typ członka __storage_type. Jak zauważa Lightning Racis w Obrit, jest nieco bardziej rygorystyczne, ponieważ wymaga nie tylko takiego typu, ale także, że można mu przypisać int (przy użyciu zwykłych zasad konwersji C++). Ogólnie można by zagwarantować istnienie takiego podtypu tylko poprzez użycie go w definicji szablonu. Chociaż gdybyś miał jakąś dziwną klasę, w której musiałbyś zagwarantować, że ten typ istniał, ale nigdy go nie używał, to chyba potrzebowałbyś dodatkowej sztuczki :) –

+0

Dzięki temu nienazwany bit btw. Jak komentuje Lightning Racis w odpowiedzi Obrita, to jest sztuczka, której mi brakowało! –

Powiązane problemy