1

Ich habe zwei variadic Klassenmitglied Funktionen. Wenn der erste Init(...) aufgerufen wird, möchte ich eine std :: -Funktion für die Memberfunktion der zweiten Klasse erstellen und dann die Argumente von Init(...) an den Funktionszeiger binden.std :: Funktion zu Variadic Member-Funktion und dann binden variadic Vorlage Argumente

So später dann kann ich einfach anrufen mf_() ohne alle Argumente zu Reset(...) wieder

Ich mag an würde passieren zu müssen vermeiden es Template-Klasse und speichern Sie die Argumente in einem Tupel zu machen.

Ich versuche, das folgende Beispiel funktioniert:

#include <iostream> 
#include <string> 
#include <functional> 

using namespace std; 

class Foo 
{ 
public: 
    template<typename... T> 
    void Init(T&... args) 
    { 
     cout << __func__ << endl; 
     Print(args...); 

     // bind args.. to Reset .. 
     mf_ = std::bind(&Reset, args...); 
     // mf_ = std::bind(&Foo::Reset, this, args...); ??? 
    } 

    template<typename... T> 
    void Reset(T&... args) 
    { 
     cout << __func__ << endl; 
    } 

    // std::function to Reset(...) 
    std::function<void()> mf_; 

private: 
    template<typename First> 
    void Print(First& arg) 
    { 
     cout << arg << endl; 
    } 

    template<typename First, typename... Rest> 
    void Print(First& arg, Rest&... args) 
    { 
     cout << arg << " "; 
     Print(args...); 
    } 
}; 

int main() 
{ 
    int arg1 = 1; 
    int arg2 = 2; 
    string arg3 { "test" }; 
    double arg4 = 1.10; 

    Foo foo; 
    foo.Init(arg1, arg2, arg3, arg4); 

    //foo.mf_(); 
    return 0; 
} 

Link zu leben Beispiel: http://cpp.sh/4ylm

Wenn ich kompilieren ich eine Fehlermeldung erhalten, die Argument Abzug

Vorlage heißt es/Substitution fehlgeschlagen: 17:37:
Hinweis: konnte den Template-Parameter '_Result'

nicht ableiten
+0

Bitte bearbeiten Sie keine Lösungen in Ihre Fragen. – Barry

Antwort

1

Das Problem ist, dass &Reset kein gültiger Zeiger-zu-Mitglied-Ausdruck ist.

Sie müssen &Foo::Reset sagen einen Zeiger auf Elementfunktion zu bilden, und Sie müssen auch den this Zeiger liefern, so dass Sie fast richtig mit:

// mf_ = std::bind(&Foo::Reset, this, args...); ??? 

Aber es ist noch nicht gültig, da Reset ist eine Funktionsvorlage und Sie müssen angeben, welche Spezialisierung der Vorlage Sie meinen.

Sie den Compiler sagen können, die Sie, indem eine explizite Template-Argumentliste wollen Spezialisierung:

mf_ = std::bind(&Foo::Reset<T&...>, this, args...); 

oder durch eine Variable des richtigen Typs zu schaffen, von &Foo::Reset initialisiert, die der Compiler Spezialisierung abzuleiten ermöglicht die Suchen Sie nach:

void (Foo::*f)(T&...) = &Foo::Reset; 
mf_ = std::bind(f, this, args...); 

oder durch ein typedef für die richtige Art zu schaffen, und &Foo::Reset auf diese Art Casting:

using pmf_type = void (Foo::*)(T&...); 
    mf_ = std::bind((pmf_type)&Foo::Reset, this, args...); 
+0

Danke! Es funktioniert. Meine ursprüngliche Frage wurde mit einer Live-Lösungsdemo aktualisiert – Ody