2015-03-17 13 views
20

To jest punkt, o którym gcc 4.9.2 i clang 3.5.2 są ostry nieporozumienia. Program:Czy argumenty funkcji zestawu parametrów mogą być domyślne?

template<typename ...Ts> 
int foo(int i = 0, Ts &&... args) 
{ 
    return i + sizeof...(Ts); 
} 

int main() 
{ 
    return foo(); 
} 

kompiluje bez komentarza z gcc (-std=c++11 -Wall -pedantic). Dzyń mówi:

error: missing default argument on parameter 'args' 

Z foo zmienione na:

template<typename ...Ts> 
int foo(int i = 0, Ts &&... args = 0) 
{ 
    return i + sizeof...(Ts); 
} 

dzyń ma żadnych skarg, ale gcc mówi:

error: parameter pack ‘args’ cannot have a default argument 

Który kompilator ma rację?

+1

Można to obejść przez przeciążeniem: 'szablonu int foo (int i, TS && ...) {return i + sizeof ... (Ts); } inline int foo() {return foo (0); } ' – Oktalist

Odpowiedz

15

Z 8.3.6 ([dcl.fct.default])/3:

domyślny argument nie określa się dla opakowania parametrów.

Z 8.3.6 dcl.fct.default ([])/4:

W danym zgłoszenia funkcji, każdy parametr Po parametru z domyślnym argumentu ma domyślny Argumentowane w tej lub poprzedniej deklaracji lub będzie pakietem parametrów funkcji.

Pozwala to na stosowanie kodu takiego jak void f(int a = 10, Args ... args), a nawet jak w przypadku pierwszego fragmentu. (Dzięki @ T.C. Za sprawdzenie drugiego zdania!)

+3

Drat! Nie była to odpowiedź, której oczekiwałem :( –

+3

[dcl.fct.default]/4 ("W deklaracji danej funkcji każdy parametr następujący po parametrze o domyślnym argumencie ma domyślny argument dostarczony w tym lub poprzednim deklaracja lub będzie pakietem parametrów funkcji. ") wydaje się zezwalać na pierwszą wersję –

+0

@KerrekSB Tak, więc zezwala na wersję zaakceptowaną przez GCC –

1

Kerrek SB mówi, że to niemożliwe. Co można zrobić, zamiast tego używa std::tuple

template <class ... Args> 
void foo(std::tuple<Args...> t = std::tuple<int>(0)) 
{}