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:
template<typename ...T>
void f(T ... args)
{
g( args... ); //pattern = args
h( x(args)... ); //pattern = x(args)
m( y(args...) ); //pattern = args (as argument to y())
n( z<T>(args)... ); //pattern = z<T>(args)
}
Jeśli teraz wywołam tę funkcję przekazując T
jako {int, char, short}
, to każde wywołanie funkcji jest interpretowane jako:
g( arg0, arg1, arg2 );
h( x(arg0), x(arg1), x(arg2) );
m( y(arg0, arg1, arg2) );
n( z<int>(arg0), z<char>(arg1), z<short>(arg2) );
W opublikowanym kodzie std::forward
następuje czwarty wzorzec zilustrowany n()
wywołaniem funkcji.
Zwróć uwagę na różnicę między x(args)...
i y(args...)
powyżej!
Możesz użyć ...
do zainicjowania tablicy również jako:
struct data_info
{
boost::any data;
std::size_t type_size;
};
std::vector<data_info> v{{args, sizeof(T)}...}; //pattern = {args, sizeof(T)}
który jest rozszerzony do tego:
std::vector<data_info> v
{
{arg0, sizeof(int)},
{arg1, sizeof(char)},
{arg2, sizeof(short)}
};
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:
template<typename ... Mixins>
struct mixture : public Mixins ... //pattern = public Mixins
{
//code
};
W tym przykładzie wzorzec jest rozwijany jako:
struct mixture__instantiated : public Mixin0, public Mixin1, .. public MixinN
Oznacza to, że mixture
dziedziczy publicznie ze wszystkich klas podstawowych.
Mam nadzieję, że to pomoże.
...
następuje przed wprowadzeniem identyfikatora. W przypadku korzystania z jednego lub obu typów pakietów następuje...
rozwinięcie po wzorcu wyrażenia.