2016-07-29 26 views
0

Ich versuche, eine Wrapper-Funktion zu schreiben, die mit einem Funktionszeiger zur Kompilierzeit verknüpft, also schrieb ich den folgenden Code, der in C++ einwandfrei funktioniert:decltype des Mitglieds Funktionszeiger als Vorlage Argument in C++ 11

#include <iostream> 

template<typename Fn, Fn func, typename... Args> 
typename std::result_of<Fn(Args...)>::type callfunc(Args&&... args){ 
    //do something else here 
    return (*func)(args...); 
} 

double add(double a, double b){ 
    return a+b; 
} 

int main(){ 
    std::cout << callfunc<decltype(&add), &add>(2.0, 3.0) << "\n"; 
} 

Allerdings, wenn ich versuche, das gleiche mit einer Elementfunktion wie diese

#include <iostream> 

template<typename Fn, Fn func, typename... Args> 
typename std::result_of<Fn(Args...)>::type callfunc(Args&&... args){ 
    //do something else here 
    return (*func)(args...); 
} 
class testclass { 
public: 
    double testadd(double a, double b); 
    void run(); 
}; 

double testclass::testadd(double a, double b){ 
    return a+b; 
} 

void testclass::run(){ 
    std::cout << 
    callfunc<decltype(&testclass::testadd), &testclass::testadd>(2.0, 3.0) 
    // ^^^^^ this won't compile! ^^^^ 
    << "\n"; 
} 

int main(){ 
    testclass obj; 
    obj.run() 
} 

ich den folgenden Compiler-Fehler zu tun:

error: indirection requires pointer operand ('double (testclass::*)(double,double)' invalid) return (*func)(args...); 

Was mache ich falsch?

Antwort

1

Um eine nicht statische Elementfunktion aufzurufen, benötigen Sie einen gültigen Instanzzeiger. Hier ist eine modifizierte Version Ihres Codes, die funktioniert:

#include <iostream> 

template<typename Fn, Fn func, typename Class, typename... Args> 
typename std::result_of<Fn(Args...)>::type callfunc(Class* instance, Args&&... args){ 
    return (instance->*func)(args...); 
} 
class testclass { 
public: 
    double testadd(double a, double b); 
    void run(); 
}; 

double testclass::testadd(double a, double b){ 
    return a + b; 
} 

void testclass::run(){ 
    std::cout << 
     callfunc<decltype(&testclass::testadd), &testclass::testadd>(this, 2.0, 3.0) 
     << "\n"; 
} 

int main(){ 
    testclass obj; 
    obj.run(); 
}