Können c ++ 11-Parameterpakete außerhalb von Vorlagen verwendet werden?
Ich habe mich gefragt, ob ich Parameterpakete haben könnte, die aus einem einzelnen, explizit angegebenen Typ bestehen. Zum Beispiel so etwas:
#include <iostream>
using namespace std;
void show() { }
template<typename First, typename... Rest>
void show(First f, Rest... rest)
{
cout << f << endl;
show(rest...);
}
void foo(int f, int... args) // error
{
show(f, args...);
}
int main()
{
foo(1, 2, 3);
}
Das Problem, das ich habe, ist mit der Definition vonfoo()
. Mit OS X clang ++ Version 5 (llvm 3.3svn) bekomme ich den Fehlererror: type 'int' of function parameter pack does not contain any unexpanded parameter packs
.
Natürlich kann ich es zum Kompilieren bringen, indem ich zu änderefoo()
in eine Funktionsvorlage:
template<typename... Args>
void foo(int f, Args... args)
{
show(f, args...);
}
Jetzt aberfoo()
werde akzeptierenint
für den ersten Parameter und alles, was für den Rest streambar ist. Zum Beispiel:
struct x { };
ostream& operator<<(ostream& o, x)
{
o << "x";
return o;
}
int main()
{
foo(1, 2, x(), 3); // compiles :(
}
Jetzt habe ich gesehendie akzeptierte Lösung hier was die Verwendung von Typmerkmalen und vorschlägtstd::enable_if
, aber das ist umständlich. Sie schlugen auch vor, mitstd::array
aber ich denke ein einfachesstd::initializer_list
Funktioniert einwandfrei und sieht sauberer aus:
void foo_impl(initializer_list<int> ints)
{
for(int i: ints)
cout << i << endl;
}
template<typename... Args>
void foo(int f, Args... args)
{
foo_impl({f, args...});
}
struct x { };
ostream& operator<<(ostream& o, x)
{
o << "x";
return o;
}
int main()
{
foo(1, 2, 3);
foo(1, 2, x(), 3); // no longer compiles
// we also get an error saying no known conversion from 'x' to 'int' :)
}
Also das ist ordentlich. Aber die Frage bleibt, ist das notwendig? Gibt es wirklich keine Möglichkeit, eine Nicht-Vorlagenfunktion zu definieren, die ein Parameterpaket eines bestimmten Typs akzeptiert? So was:
void foo(int... args) { }