У контексті варіативного шаблону еліпсис ...
використовується для розпакування пакета параметрів шаблону, якщо він з’являється в правій частині виразу (на момент зателефонуйте до цього шаблону виразів ). Правило полягає в тому, що будь-який візерунок з лівої сторони ...
повторюється - розпаковані візерунки (називаємо їх виразами зараз) відокремлюються комою ,
.
Це можна найкраще зрозуміти на деяких прикладах. Припустимо, у вас є такий шаблон функції:
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)
}
Тепер, якщо я називаю цю функцію передачею T
як {int, char, short}
, то кожен виклик функції розгортається як:
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) );
У опублікованому вами коді std::forward
слідує четвертий візерунок, проілюстрований n()
функцією виклику.
Зверніть увагу на різницю між x(args)...
і y(args...)
вище!
Ви можете використовувати ...
ініціалізацію масиву також як:
struct data_info
{
boost::any data;
std::size_t type_size;
};
std::vector<data_info> v{{args, sizeof(T)}...}; //pattern = {args, sizeof(T)}
який розширюється на це:
std::vector<data_info> v
{
{arg0, sizeof(int)},
{arg1, sizeof(char)},
{arg2, sizeof(short)}
};
Я щойно зрозумів, що модель може включати навіть специфікатор доступу, як public
, як показано в наступному прикладі:
template<typename ... Mixins>
struct mixture : public Mixins ... //pattern = public Mixins
{
//code
};
У цьому прикладі шаблон розширюється як:
struct mixture__instantiated : public Mixin0, public Mixin1, .. public MixinN
Тобто mixture
виходить публічно з усіх базових класів.
Сподіваюся, що це допомагає.
...
перед початком введення ідентифікатора йдеться. Якщо ви використовуєте один або обидва типи пачок,...
після виразного шаблону з'являється розширення.