2015-07-27 2 views
3

У меня с трудом понимается расширение пакета параметров. То, что меня смущает, - это то, что на правой стороне появляются точки, а с левой стороны - точки. Я наткнулся на сообщение this, которое немного помогло. Предположу, у меня есть следующие два примераШаблоны Variadic - понимание расширения пакета параметров

Example 1: 
template <class ...A> --> line 1 
int func(A... arg)  --> line 2 
{ 
    return sizeof...(arg); 
} 

int main(void) 
{ 
    return func(1,2,3,4,5,6); 
} 

Сообщение я уже упоминался выше, я считаю, упоминает, что разница ч/б ...A и A... является то, что первый делает левую сторону расширение, а второй делает правое боковое расширение. Я не уверен, что это значит. Может ли кто-нибудь прояснить это с помощью того, как что-то будет выглядеть при расширении. Единственное, что я понимаю, до сих пор относительно точек на правой стороне являются такие примеры, как это

//Foo and bar are variadic parameter packs 
Foo...      => Foo1, Foo2, Foo3, etc 
std::vector<Foo>...  => std::vector<Foo1>, std::vector<Foo2>, std::vector<Foo3>, etc. 
std::tuple<Foo...>(bar...) => std::tuple<Foo1, Foo2, Foo3, etc>(bar1, bar2, bar3, etc) 
&bar...     => &bar1, &bar2, &bar3, etc 

может любой, пожалуйста, уточнить, какие точки расширения в линии 1 и линии 2 и в чем разница между левой боковое расширение и расширение правой стороны?

+2

Пространства вокруг точек не имеют значения. Поэтому 'class ... A' эквивалентен' class ... A', а 'A ... arg' эквивалентен' A ... arg'. Только 'sizeof ...' не может иметь пробелов. – dyp

+0

@dyp Вы уверены в 'sizeof ...'? –

+0

@ T.C. Не совсем. В стандарте есть несколько советов, например: «Оператор' sizeof ... '* .. – dyp

ответ

2

Нет «расширения слева», существует только «расширение справа». Когда вы набрали:

template <class ...A> 
int func(A... arg) 

... не относится к A. Это помогает думать о нем, как:

template <class... A> 

как, A имен параметра набивки, состоящей из class эсов. В этой строке не происходит расширения - это просто объявление параметров для шаблона функции func.

Кроме того, как указывает T.C., в списке аргументов в списке аргументов грамматически привязывается имя аргумента, а не его тип. Это помогает понять смысл особо сложных заявления, такие как:

template <typename... T> 
void foo(T (*...fs)()); 

fs где бы (возможно, пустой) пакет указателей на нульарные функции.

Что касается расширения пакета параметров, см. Мой ответ here для получения списка примеров того, какое расширение параметра основано на размещении .... Краткая версия: все пакеты в выражении, непосредственно предшествующие ..., расширяются одновременно. Все примеры, перечисленные в вашем вопросе, верны. Я бы дополнительно добавил:

std::tuple<Foo...>(bar...) => std::tuple<Foo1, Foo2, Foo3, etc>(bar1, bar2, bar3, etc) 
std::tuple<Foo>(bar)... => std::tuple<Foo1>(bar1), std::tuple<Foo2>(bar2), ... 
+1

Я бы сказал, что 'class ... A' is about * contraction * , а не расширение. Превращение группы типов в один пакет. В то время как «A ...'идет о расширении, расширяя один пакет в группу типов. например если вы явно вызываете 'func (1, '1', 1.0)', то вы * строите * пакет, а не * расширяете его. –

+3

Полезно знать, что в 'A ... args',' ... 'связывается с' args' как вопрос грамматики. Некоторые более сумасшедшие декларанты не имеют большого смысла, если вы этого не знаете. –

+1

@ T.C. Обновлено, с сумасшедшим декларатором. – Barry

Смежные вопросы