W C ++ 11 istnieją różne szablony, takie jak ten:
template< class T, class... Args >
unique_ptr<T> make_unique( Args&&... args )
{
return unique_ptr<T>(new T(std::forward<Args>(args)...));
}
Jest kilka ciekawostek na ten temat: wyrażenie std::forward<Args>(args)...
używa obu Args
i args
tylko jednego ...
tokenu. Ponadto std::forward
jest to niezmienna funkcja szablonu, która pobiera tylko jeden parametr szablonu i jeden argument. Jakie są dla tego reguły składni (w przybliżeniu)? Jak można to uogólnić?
Ponadto: W implementacji funkcji wielokropek ( ...
) znajduje się na końcu wyrażenia zainteresowania. Czy istnieje powód, dla którego na liście argumentów szablonu i liście parametrów wielokropek znajduje się pośrodku?
c++
c++11
variadic-templates
Ralph Tandetzky
źródło
źródło
...
następuje przed wprowadzeniem identyfikatora. W przypadku korzystania z jednego lub obu typów pakietów następuje...
rozwinięcie po wzorcu wyrażenia.Odpowiedzi:
W kontekście szablonu wariadycznego wielokropek
...
służy do rozpakowywania pakietu parametrów szablonu, jeśli pojawia się on po prawej stronie wyrażenia (wywołaj na chwilę ten wzorzec wyrażenia ). Zasada jest taka, że każdy wzorzec znajdujący się po lewej stronie...
jest powtarzany - rozpakowane wzorce (nazwijmy je teraz wyrażeniami ) są oddzielane przecinkiem,
.Najlepiej można to zrozumieć na kilku przykładach. Załóżmy, że masz ten szablon funkcji:
Jeśli teraz wywołam tę funkcję przekazując
T
jako{int, char, short}
, to każde wywołanie funkcji jest interpretowane jako:W opublikowanym kodzie
std::forward
następuje czwarty wzorzec zilustrowanyn()
wywołaniem funkcji.Zwróć uwagę na różnicę między
x(args)...
iy(args...)
powyżej!Możesz użyć
...
do zainicjowania tablicy również jako:który jest rozszerzony do tego:
Właśnie zdałem sobie sprawę, że wzorzec może nawet zawierać specyfikator dostępu, taki
public
jak pokazano w poniższym przykładzie:W tym przykładzie wzorzec jest rozwijany jako:
Oznacza to, że
mixture
dziedziczy publicznie ze wszystkich klas podstawowych.Mam nadzieję, że to pomoże.
źródło
x+args...
należy rozszerzyć dox+arg0,x+arg1,x+arg2
, a niex+arg0,arg1,arg2
....
odnosi się do każdej rozwijalnej jednostki we wzorcu.x+args...
powinien się rozszerzyćx+arg0,x+arg1,x+arg2
, a niex+arg0,arg1,arg2
.sizeof...(T)
nie jest tam potrzebne. Możesz po prostu napisać:int a[] = { ___ };
Poniższy fragment pochodzi z wykładu „Variadic Templates are Funadic” wygłoszonego przez Andrei Alexandrescu na GoingNative 2012. Mogę go polecić jako dobre wprowadzenie do wariadycznych szablonów.
Są dwie rzeczy, które można zrobić z pakietem wariadycznym. Można zastosować,
sizeof...(vs)
aby uzyskać liczbę elementów i ją rozwinąć.Zasady rozbudowy
Ekspansja postępuje do wewnątrz na zewnątrz. Przy rozszerzaniu dwóch list w trybie lock-step muszą one mieć ten sam rozmiar.
Więcej przykładów:
Rozwija wszystko
Ts
na liście argumentów szablonu,A
a następnie funkcjahun
zostaje rozszerzona o allvs
.Rozwija all
Ts
na liście argumentów szablonuA
i allvs
jako argumenty funkcji dlahun
.Rozszerza funkcję za
hun
pomocąTs
iw trybievs
lock-step.Uwaga:
Ts
nie jest typem ivs
nie jest wartością! Są to aliasy listy typów / wartości. Każda lista może być potencjalnie pusta. Obaj wykonują tylko określone czynności. Więc nie jest możliwe:Rozwinięcie loci
Argumenty funkcji
Listy inicjalizujące
Podstawowe specyfikatory
Listy inicjatorów członków
Utwórz tymczasowe listy argumentów
Kompiluje się tylko wtedy, gdy istnieje możliwość dopasowania argumentów.
Listy przechwytywania
Listy atrybutów
Jest w specyfikacji, ale nie ma jeszcze atrybutu, który można wyrazić jako typ.
źródło