непонятки с variadic templates
От: watchyourinfo Аргентина  
Дата: 19.08.14 01:04
Оценка:
У меня сейчас скомпилировался (gcc двухлетней давности) и даже успешно прошел тесты код с таким шаблоном:

template<typename ...Args, typename CbIn, typename CbOut = CbIn>


очевидно здесь налицо неоднозначность: если я инстанцирую это как <X, Y, Z> то что это:
Args=(X Y), CbIn=Z, CbOut=Z
или
Args=(X), CbIn=Y, CbOut=Z
??

Эта неоднозначность у меня видимо как-то устранилась за счет использования типов аргументов.

Я не могу понять, как на это дело смотрит стандарт?
Это должно компилироваться вообще??
Re: непонятки с variadic templates
От: flаt  
Дата: 19.08.14 07:14
Оценка:
Здравствуйте, watchyourinfo, Вы писали:


W>

W> template<typename ...Args, typename CbIn, typename CbOut = CbIn>


W>Я не могу понять, как на это дело смотрит стандарт?

W>Это должно компилироваться вообще??

error: parameter pack ‘Args’ must be at the end of the template parameter list

GCC, VC.
Re: непонятки с variadic templates
От: uzhas Ниоткуда  
Дата: 19.08.14 08:45
Оценка: 1 (1)
Здравствуйте, watchyourinfo, Вы писали:

W>Я не могу понять, как на это дело смотрит стандарт?


в стандарте этот момент описан очень мутно
вот что я нашел:

14.1 Template parameters [temp.param]

11 If a template-parameter of a class template or alias template has a default template-argument, each subsequent
template-parameter shall either have a default template-argument supplied or be a template parameter
pack. If a template-parameter of a primary class template or alias template is a template parameter pack, it
shall be the last template-parameter.
A template parameter pack of a function template shall not be followed
by another template parameter unless that template parameter can be deduced from the parameter-type-list
of the function template or has a default argument
(14.8.2). [ Example:
template<class T1 = int, class T2> class B; // error
// U can be neither deduced from the parameter-type-list nor specified
template<class... T, class... U> void f() { } // error
template<class... T, class U> void g() { } // error
—end example ]

14.8.2 Template argument deduction [temp.deduct]
...
2 When an explicit template argument list is specified, the template arguments must be compatible with the
template parameter list and must result in a valid function type as described below; otherwise type deduction
fails. Specifically, the following steps are performed when evaluating an explicitly specified template
argument list with respect to a given function template:
— The specified template arguments must match the template parameters in kind (i.e., type, non-type,
template). There must not be more arguments than there are parameters unless at least one parameter
is a template parameter pack
, and there shall be an argument for each non-pack parameter. Otherwise,
type deduction fails.
— Non-type arguments must match the types of the corresponding non-type template parameters, or must
be convertible to the types of the corresponding non-type parameters as specified in 14.3.2, otherwise
type deduction fails.
— The specified template argument values are substituted for the corresponding template parameters as
specified below.
...
14.8.2.1 Deducing template arguments from a function call [temp.deduct.call]
...
1 ...
For a function parameter pack that occurs at the end of the parameter-declaration-list,
the type A of each remaining argument of the call is compared with the type P of the declarator-id of the
function parameter pack. Each comparison deduces template arguments for subsequent positions in the
template parameter packs expanded by the function parameter pack. When a function parameter pack
appears in a non-deduced context (14.8.2.5), the type of that parameter pack is never deduced.

14.8.2.5 Deducing template arguments from a type [temp.deduct.type]
...
5 The non-deduced contexts are:
...
— A function parameter pack that does not occur at the end of the parameter-declaration-list.


то есть для шаблонных функций возможны случаи, когда parameter pack не последний, но не представляю какие
а также возможно указание нескольких parameter packs

W>Это должно компилироваться вообще??

с точки зрения логики я бы поддержал parameter pack только в самом конце списка типов, иначе алгоритм сопоставления типов может усложниться и вызывать неоднозначности
Re[2]: непонятки с variadic templates
От: watchyourinfo Аргентина  
Дата: 19.08.14 08:58
Оценка:
F>

error: parameter pack ‘Args’ must be at the end of the template parameter list

F>GCC, VC.

я забыл указать, у меня метод класса, а не сам класс
Re[2]: непонятки с variadic templates
От: Ku-ku  
Дата: 26.08.14 09:52
Оценка: 1 (1)
Здравствуйте, uzhas, Вы писали:

U>то есть для шаблонных функций возможны случаи, когда parameter pack не последний, но не представляю какие

U>а также возможно указание нескольких parameter packs

Например,

template <class... Args>
struct X { /*...*/ };

template <class... Args>
struct Y { /*...*/ };

template <class... Args1, class... Args2>
void f(X<Args1...>, Y<Args2...>) { /*...*/ }

int main()
{
    f(X<int, char>(), Y<void, bool, double>());
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.