meine ich nicht den letzten Grund zu geben, warum die Spezialisierung nicht vorgesehen ist (ich weiß nicht, dass), aber vielleicht könnte ich auf einige der technischen Hindernisse hinweisen, die bei der Implementierung auftreten könnten. Das wird dir hoffentlich ein Gefühl geben, warum die Spezialisierung nicht da ist.
Betrachten wir zuerst, wie die std::function<>
Klassenvorlage selbst implementiert werden könnte. Die Art Löschtechnik, die das Design zugrunde liegt, skizziert werden könnte wie folgt (dies ist nur eine illustrative Vereinfachung, die reale Umsetzung ist viel komplexer):
#include <memory>
template<typename T>
struct function { };
template<typename R, typename... Args>
struct function<R(Args...)>
{
public:
template<typename F>
function(F&& f) : _holder(
new holder<typename std::decay<F>::type>(std::forward<F>(f))
)
{ }
R operator() (Args&&... args)
{ _holder->call(std::forward<Args>(args)...); }
private:
struct holder_base
{ virtual R call(Args&&... args) = 0; };
template<typename F>
struct holder : holder_base
{
holder(F&& f) : _f(std::forward<F>(f)) { }
R call(Args&&... args) { return _f(std::forward<Args>(args)...); }
F _f;
};
std::unique_ptr<holder_base> _holder;
};
Nun wollen sie sehen, wie die Spezialisierung für Ellipsen aussehen würde, . Zuallererst sind die Anzahl und der Typ der Argumente, die für eine variadische Funktion bereitgestellt werden, nicht, die in der Signatur dieser Funktion festgelegt sind. Daher muss der Call-Betreiber unserer spezialisierten Vorlage eine Vorlage-Funktion eine beliebige Anzahl und Art der Argumente zu akzeptieren sein:
template<typename R, typename... Args>
struct function<R(Args.......)>
{
...
template<typename... Ts>
R operator() (Args&&... args, Ts&&... ts)
{ _holder->call(std::forward<Args>(args)..., std::forward<Ts>(ts)...); }
...
Dies zwingt uns, die wiederum holder<>
‚s Call-Betreiber eine variadische Funktion Vorlage zu machen. Um jedoch das Löschen des Typs zu realisieren, muss derselbe Aufrufoperator virtual
sein, und Funktionsschablonen können in C++ nicht virtual
sein.
Die Dinge wären sicherlich einfacher, wenn variadic Argumente (ich spreche hier über Ellipsen) leicht weitergeleitet werden können, ohne zu variadischen Template-Parameter und perfekte Weiterleitung zurückzukehren. Ich bin mir jedoch nicht bewusst, dass dies auf einfache Art und Weise erreicht werden kann, und insbesondere nicht, wenn kein anderes Argument an die Funktion übergeben werden soll als diejenigen, die der variadischen Liste entsprechen.
Haben Sie eine Vorlage getestet, die so aussieht, um zu sehen, ob sie funktioniert? – Omnifarious
Beide Snippets zeigen völlig verschiedene Dinge. Variadic Vorlagen werden zur Kompilierzeit behandelt. Die Variablen des Typs "C" werden zur Laufzeit behandelt. – mfontanini
Die Parametersyntax '...' (nicht in der variadic-Vorlage) wird aus Gründen der Abwärtskompatibilität mit C beibehalten. Von der Verwendung wird stark abgeraten. –