2014-02-27 3 views
6

Ich fühle mich ein wenig unwohl im Moment, wenn ich Parameterpacks verwende. Ich habe eine Funktion bekamWie behandelt man Parameterpakete in der Mitte einer Funktionssignatur?

template <class ... Args> 
void f(int x, Args ... args, int y) 
{} 

und natürlich mit es wie folgt funktioniert:

f(5, 3); 

Ich frage mich, warum der folgende Aufruf fehlschlägt:

f(5, 3.f, 3); 

Es scheint wie eine gerade -forward Verwendung von Parameter-Packs zu mir, aber nach dem Compiler Args ist nicht erweitert.

Natürlich könnte ich leicht ersetzen f durch:

template <class ... Args> 
void f(int x, Args ... args) 
{ 
    static_assert(sizeof...(args) >= 1, ...); 
    extract y from args ... 
} 

Fragen:

  • Warum kann ich Parameter Packs wie diese verwenden? Es sieht so aus, als ob der Compiler den Ersetzungscode leicht erstellen könnte. Oder gibt es Probleme mit dem Ersatz f() oben?

  • Was ist der beste Weg, um damit umzugehen, wenn die Reihenfolge der Parameter wirklich wichtig für mich ist? (Denken Sie an std::transform für eine beliebige Anzahl von Eingabe-Iteratoren.)

  • Warum ist die Verwendung von Parameterpaketen in der obigen Situation nicht verboten? Ich nehme an, es ist, weil sie explizit, z. f<float>(5, 3.f, 3)?

Antwort

2

Warum kann ich nicht Parameter-Packs wie diese? Es sieht so aus, als ob der Compiler den Ersetzungscode leicht erstellen könnte. Oder gibt es Probleme mit dem Ersatz f() oben?

Könnte in diesem speziellen Fall einfach sein, möglicherweise nicht in anderen. Die wirkliche Antwort ist, dass der Standard das Verhalten spezifiziert und der Standard keine Transformation spezifiziert hat und im Allgemeinen selten tut.

Ich möchte darauf hinweisen, dass Ihre Transformation nicht mit SFINAE funktioniert, da static_assert Hart Fehler sind, so bin ich froh, die Transformation nicht durchgeführt wird. (Hinweis: Was ist, wenn f ist überlastet mit einer einzigen Argumente Version ein float nehmen, die für f(1) mit/ohne Transformation erhalten gewählt würden?)

Was ist der beste Weg, damit umzugehen, wenn die Reihenfolge der Parameter ist mir wirklich wichtig?(Denken Sie an std::transform für eine beliebige Anzahl von Eingabe-Iteratoren.)

Explizit die Vorlage Pack-Parameter angeben.

Warum ist die Verwendung von Parameterpaketen in der obigen Situation nicht verboten? Ich nehme an, es ist, weil sie explizit, z. f (5, 3.f, 3)?

Ich denke, dass Ihre Annahme ist genau richtig; Wenn explizit angegeben, funktioniert dies wie erwartet.

+0

Danke, dass Sie mich in diesem Fall auf SFINAE aufmerksam gemacht haben. Ich bin mir ziemlich sicher, dass ich eine Lösung finden könnte, die die meisten Fälle korrekt behandelt, aber jetzt bin ich mir auch sicher, dass es sich nicht lohnt (in meiner Situation). –

1

Es ist ein Fall von Ihnen können andere nicht-variadische Template-Parameter haben, aber erst, nachdem diese nicht-variadische Argumente zu den nicht-variadische Parameter zugeordnet sind, können die Reste bilden die Parametersatz für den variadische Parameter . Sie müssen also die int y am Ende Ihrer Argumentliste vor die variadischen Parameter verschieben. Etwas wie:

template <class... Args> 
void f(int x, int y, Args... args) 
{}