Ich möchte eine Klasse erstellen, als wenn instanziiert, akzeptiert eine variable Anzahl von Funktionsreferenzen, die keine Signaturen zuvor bekannt haben. Hier ist ein Beispiel, das fast das tut, was ich will:Eine Klasse, die Variablenfunktionsreferenzen unbekannter Signatur akzeptieren kann
// To show the function refs being used
void p(int arg) { cout << "int " << arg << endl; }
void p(string arg) { cout << "string " << arg << endl; }
void p(int arg1, int arg2) { cout<<"int/int "<<arg1<<arg2<<endl; }
void p(int arg1, string arg2) { cout<<"int/string "<<arg1<<arg2<<endl; }
class foo {
public:
// CTOR takes variadic function refs
template <typename... Args>
foo(Args... args) { p(args()...); }
// "args()..." requires supplied functions to take no parameters
// but makes no requirement on their return values.
};
// Using lambdas, but free functions, std::bind(), etc. work too
foo i([]{return 1;}); // prints "int 1"
foo s([]{return string("one");}); // prints "string one"
foo b([]{return 2;},
[]{return string("two");}); // prints "int/string 2two"
Was kann ich nicht sehen, wie dieses Problem zu beheben, so dass die als Argumente geliefert Funktionen nicht im Konstruktor ausgewertet werden. Ich möchte, dass der Anruf zu p(args()...)
zu einem späteren Zeitpunkt erfolgt, durch eine andere Methode in foo
. Deshalb kann foo nicht so einfach erstellt werden wie foo i(1)
: Die Argumentfunktion (en) müssen später und mehrfach aufgerufen werden, nicht nur einmal, wenn das Objekt erstellt wird (und sie sind komplexer, als nur ein Konstante).
Das Problem scheint zu speichern Referenzen auf den Konstruktor Parameter später aufgerufen werden, wenn die Klasse nicht wissen, wie viele oder welche Signatur diese Parameter haben. Irgendwie müssen die Argumente Teil einer Klassenvorlage und nicht nur einer Konstruktorvorlage sein, aber wie?
Wenn die übergebenen Funktionen alle die gleiche Signatur haben, dann könnte man eine Klassenvorlage mit einem Nicht-Typ-Parametern verwenden und die Funktionen als Vorlage Argumente liefern:
template <int (&...Arg)()>
class bar {
public:
bar() { p(Arg()...); }
other() { p(Arg()...); } // Use in any method
};
int one() { return 1; }
int two() { return 2; }
bar<one> bi; // Prints "int 1"
bar<one, two> bii; // Prints "int/int 12"
Dies erfordert jedoch alle Argumente Funktionen sein that return int und funktioniert auch nicht mit lambdas, da sie keine Template-Argumente sein können.
ich diese Zeilen lesen und Lisp denke. –