2015-03-17 10 views
20

Dies ist ein Punkt, über den gcc 4.9.2 und clang 3.5.2 in scharfen Meinungsverschiedenheiten sind. Das Programm:Können Argumente für Parameterpakete-Funktionen voreingestellt werden?

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

int main() 
{ 
    return foo(); 
} 

kompiliert ohne Kommentar von gcc (-std=c++11 -Wall -pedantic). Clang sagt:

error: missing default argument on parameter 'args' 

Mit foo geändert:

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

Klirren hat keine Beschwerden, aber gcc sagt:

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

Welche Compiler ist richtig?

+1

mit Man könnte es umgehen, durch Überlastung: 'template int foo (int i, Ts && ...) {return i + sizeof ... (Ts); } Inlineinhalt foo() {return foo (0); } ' – Oktalist

Antwort

15

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

Ein Standardargument ist nicht für einen Parameter Packung angegeben werden.

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

In einer bestimmten Funktionsdeklaration, jeder Parameter im Anschluss an einen Parameter mit einem Standardargument ist ein Standard-Argument geliefert in dieser oder einer früheren Deklaration oder soll ein Funktionsparameter-Paket sein.

So ermöglicht Code wie void f(int a = 10, Args ... args), oder tatsächlich wie Ihr erstes Schnipsel. (Danke an @ T.C. Für Nachschlagen des zweiten Satzes!)

+3

Drat! Das war nicht die Antwort, die ich wollte :( –

+3

[dcl.fct.default]/4 ("In einer bestimmten Funktionsdeklaration muss jeder Parameter, der auf einen Parameter mit einem Standardargument folgt, ein Standardargument in diesem oder einem vorherigen Argument enthalten Deklaration oder soll ein Funktionsparameter-Paket sein. ") scheint die erste Version zu erlauben. –

+0

@KerrekSB Ja, so erlaubt es die von GCC akzeptierte Version. –

1

Ein Kerrek SB sagt, es ist nicht möglich. Was Sie tun können, stattdessen wird ein std::tuple

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