2012-02-08 3 views
13

jestem przyzwyczajony do ostrych nawiasach są wykorzystywane do określenia rodzaju, jako parametr:Co to są nawiasy ostrych wartości argumentów i do czego jest używany?

vector<int> vecOfInts ; 

Ale w rapidjson istnieje kod tak:

document.Parse<0>(json) ; 

podpis document.Parse METHOD jest:

template <unsigned parseFlags> 
GenericDocument& Parse(const Ch* str) { 
    RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); 
    GenericStringStream<Encoding> s(str); 
    return ParseStream<parseFlags>(s); 
} 

Nie wiedziałem, że można przekazać wartość o wartości w wsporniki kątowe boczne - same nawiasy klamrowe były używane tylko w nazwach.

Co tu robi kod i dlaczego w nawiasach ostrych podaje wartość o wartości?

Czy to dobry pomysł? Gdy?

+0

możliwy duplikat [Przyczyna użycia parametru szablonu typu non zamiast zwykłego parametru?] (Http://stackoverflow.com/questions/7395700/reason-for-using-non-type-template-parameter-instead- of-regular-parameter) –

+2

Wyszukaj "parametr szablonu non-type". –

Odpowiedz

18

Są tu dwa różne czynniki.

Po pierwsze, możliwe jest zdefiniowanie szablonów, które są sparametryzowane przez rzeczy inne niż tylko typy. Na przykład, oto prosty typ array:

template <typename T, size_t N> struct Array { 
    T arr[N]; 
}; 

Możemy to wykorzystać jak

Array<int, 137> myArray; 

Wiemy, że vector<int> i vector<double> są różne typy. Ale teraz musimy również zwrócić uwagę, że Array<int,137> i Array<int,136> to różne typy.

Po drugie, podczas korzystania z szablonów, kompilator musi być w stanie znaleźć wartość dla wszystkich argumentów szablonu. Gdy używasz klas szablonów, zazwyczaj podajesz wszystkie argumenty szablonu. Na przykład nie mów: vector x, ale powiedz coś w stylu: vector<double> x. Podczas korzystania z funkcji szablonu, przez większość czasu kompilator może obliczyć argumenty. Na przykład, aby użyć std::sort, wystarczy powiedzieć coś

std::sort(v.begin(), v.end()); 

Jednakże, można również napisać

std::sort<vector<int>::iterator>(v.begin(), v.end()); 

być bardziej wyraźne. Ale czasami masz funkcję szablonu, dla której nie wszystkie argumenty mogą być odgadnięte. W przykładzie mamy to:

template <unsigned parseFlags> 
GenericDocument& Parse(const Ch* str) { 
    RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); 
    GenericStringStream<Encoding> s(str); 
    return ParseStream<parseFlags>(s); 
} 

Zauważ, że parametr parseFlags szablon nie można wywnioskować jedynie z argumentów funkcji. W związku z tym, aby wywołać tę funkcję, musisz podać parametr szablonu, ponieważ w przeciwnym razie kompilator nie może go znaleźć. To dlaczego chcesz napisać coś podobnego

Parse<0>(myString); 

Tu 0 jest argumentem szablonu (rozwiązany w czasie kompilacji) i myString jest rzeczywisty argument (rozwiązany w czasie wykonywania).

Możesz faktycznie mieć metody, które łączą trochę wnioskowania typu i trochę jawnych parametrów. Na przykład w Boost jest funkcja lexical_cast, która może wykonywać konwersje do i od typów łańcuchów. Funkcja Podpis przekonwertować z typu non-ciąg do typu string jest

template <typename Target, typename Source> 
    Target lexical_cast(const Source& arg); 

Tutaj, jeśli zadzwonisz lexical_cast, kompilator może dowiedzieć się, co Source jest, ale nie można wywnioskować Target bez pewnych wskazówek. Aby korzystać lexical_cast zatem chcesz napisać coś podobnego

std::string myString = boost::lexical_cast<std::string>(toConvertToString); 

Bardziej ogólnie, kompilator mówi, że trzeba podać jakąś liczbę argumentów szablonu (opcjonalnie 0) i będzie starał się wyprowadzić resztę. Jeśli to możliwe, świetnie! Jeśli nie, jest to błąd podczas kompilacji. Korzystanie z tego, jeśli chcesz, możesz napisać funkcję jak

template <int IntArgument, typename TypeArgment> 
    void DoSomething(const TypeArgument& t) { 
     /* ... */ 
} 

Aby wywołać tę funkcję, trzeba by powołać go tak:

DoSomething<intArg>(otherArg); 

Tutaj działa to bo ciebie musi jawnie powiedzieć kompilatorowi, co to jest IntArgument, ale wtedy kompilator może wydedukować TypeArgument z typu argumentu na DoSomething.

Mam nadzieję, że to pomoże!

Powiązane problemy