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.
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
Miałem na myśli T t, nie klasę T. Naprawiono to. –
@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ć? –