2015-05-20 33 views

Odpowiedz

0

Ta reguła dotyczy tylko szablonów klas, a nie funkcji, ponieważ szablony można wyprowadzić dla funkcji. Jeśli spróbujesz że na szablonie klasy, zobaczysz błąd:

template <class... X, class Y> 
class C { // This won't compile. 
}; 

Aby uzyskać więcej informacji na ten temat można znaleźć na stronie 7 w http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf:

If a template-parameter of a class template is a template parameter pack, it must be the last template-parameter. Note: This is not a requirementThese are not requirements for function templates because template arguments might be deduced (14.8.2)

0

Pierwsze połączenie f(12) jest chory -formowane. Parametr sztuk, które nie znajdują się na końcu parametru-zgłoszenia jest nie wynikają kontekstu w [temp.deduct.type] /p5.7:

The non-deduced contexts are:

— [..]

A function parameter pack that does not occur at the end of the parameter-declaration-list

dalszej [temp.deduct.call ]/p1:

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.

[ Example:

template<class ... Types> void f(Types& ...); 
template<class T1, class ... Types> void g(T1, Types ...); 
template<class T1, class ... Types> void g1(Types ..., T1); 

void h(int x, float& y) { 
    const int z = x; 
    f(x, y, z); // Types is deduced to int, float, const int 
    g(x, y, z); // T1 is deduced to int; Types is deduced to float, int 
    g1(x, y, z); // error: Types is not deduced 
    g1<int, int, int>(x, y, z); // OK, no deduction occurs 
} 

— end example ]

Zatem parametr X... paczka nie można wywnioskować argumentów funkcja i odliczenie szablon argumentu nie powiedzie się. GCC akceptuje pierwsze połączenie zamiast odrzucać szablon, aby nie wydedukować 12, więc wydaje się być błędem.

Drugie połączenie, f<int, int, int>(1, 2, 3, 4), jest jednak dobrze uformowane zgodnie z [temp.deduct]/p6. Wyraźnie określone argumenty szablonu są natychmiast zastępowane parametrami szablonu szablonu funkcji. Oznacza to X = {int, int, int}. Szablon odliczenie argumentu następnie przystępuje Y jest wyprowadzana z prawej skrajnej argumentu jako int:

At certain points in the template argument deduction process it is necessary to take a function type that makes use of template parameters and replace those template parameters with the corresponding template arguments. This is done at the beginning of template argument deduction when any explicitly specified template arguments are substituted into the function type, and again at the end of template argument deduction when any template arguments that were deduced or obtained from default arguments are substituted.

Należy zauważyć, że także ([temp.deduct]/p2)

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.

Szczęk nie przyjmuje ostatniej funkcji zadzwoń, ale GCC to robi. Uważam, że to błąd Clang.


Należy pamiętać, że istnieje otwarta CWG issue 1609 dotyczące stosowania domyślnych argumentów po wystąpieniu parametru-pack. Jest też LLVM Bug 21774, który kwestionuje zachowanie Clanga w tym kontekście.

Powiązane problemy