2013-04-13 13 views
21

Czytałem this i starałem się zrozumieć, co było N3601. Powiedział, że ten idiom pojawia się dużo w wyszukiwaniu w Internecie, ale nie mogłem nic znaleźć. Jaki jestCo to jest szablon <typename T, T t> idiom?

template<typename T, T t> 

idiom, co to rozwiązać, jak jest on używany, co jest niejawne są parametry szablonu, a co propozycja zmierza do ustalenia?

+2

Zacznij od szablonu 'template void foo (T t);'. Ustaw ten parametr jako wartość czasu kompilacji: 'szablon void bar();' (Myślę, że miałeś na myśli to zamiast 'class'). Teraz pomyśl, jak możesz nazwać 'foo (5);' aby T było 'int', ale aby to zrobić z' bar', potrzebujesz 'bar ();'. Czy to idzie w dobrym kierunku? – chris

+0

Miałem na myśli T t, nie klasę T. Naprawiono to. –

+0

@chris Widzę, dokąd zmierzasz. bar musi być ogólny na każdym typie, który mu dajemy, ale przyjmuje również wartość tego samego typu, co inny parametr szablonu. Musimy określić zarówno typ, jak i wartość, aby wywnioskować, że 5 to int. Wniosek pokazuje użycie tego w bibliotece refleksji, ale nigdy nie widziałem jej do dzisiaj. Jak inaczej można to wykorzystać? –

Odpowiedz

15

Problem, który jest rozwiązywany, polega na wyprowadzaniu typów z parametrów nietypowych szablonu.

Dane:

template<typename T> void foo(T); 
template<typename T, T> void bar(); 

można wywnioskować T dla foo (np foo(10) spowoduje T jest wywnioskować być int), ale to nie jest możliwe, aby wydedukować T dla bar (bar<10>() będzie po prostu nie kompiluj, musisz napisać to jako bar<int,10>()).

N3601 proponuje ustalenie tego wprowadzając składnię:

template<using typename T, T> void bar(); 

który pozwoli bar<10>() skompilować i powodować rodzaj T aby wywnioskować.

5

Wprowadzenie papier jest mylące: idiom jest rzeczywiście

template <typename T, T t> 

To oznacza szablon, który zależy od rodzaju T i wartością t tego typu. Zapis jest trochę ciężki, ponieważ w większości sytuacji typ można wywnioskować z samej wartości.

E.g.

// the current definition notation 
template <typename T, T t> void f() { t.f(); }; 

//// the proposed definition notation 
//// the parameter t depends on an implicit typename parameter T 
// template <using typename T, T t> void f() { t.f(); }; 

struct foo { 
    void f(){ 
     // some computation 
    } 
}; 

foo bar; 

int main(){ 
    // the current instantiation notation 
    f<foo,bar>(); 
    //// the proposed instantiation notation 
    //// we know that bar is of type foo, so we don't need to specify it 
    // f<bar>(); 
} 

Propozycja polega na wprowadzeniu odrobiny "cukru syntaktycznego" w celu ułatwienia zapisu.

Również powyższy przykład jest banalny w swoim opisie (i prawdopodobnie błędny, ponieważ parametry szablonu muszą być constexpr), ale w dokumencie opisano kilka sytuacji, w których aktualna notacja może stać się dość owłosiona, zmniejszając czytelność i ogólną łatwość programowanie.

+0

, a wartość 't' tego typu musi być stałą całkową lub wskaźnikiem, ponieważ nic nie jest dozwolone w szablonach. –

Powiązane problemy