2017-12-15 15 views
2

Das kleine Programm unten, das kompiliert und ausgeführt wird, ermöglicht eine Laufzeitvariable index vom Typ unsigned mit einer Reihe von Template-Funktionen mit einer zu überbrücken Vorlagenargument J vom Typ unsigned.Verwenden Sie die Signatur einer generischen Funktion abhängig von einem Nicht-Typ Vorlageargument als Vorlage Vorlage Argument

Falls weitere Erläuterungen benötigt werden, ist dies in this question besser erklärt.

Die Hilfsfunktionen, die ich geschrieben habe, verwenden ein Template-Template-Argument, um so viele Informationen wie möglich von der ursprünglichen Funktion abzuleiten. Das Problem ist, dass ich keinen besseren Weg finden konnte, das Template-Template-Argument FunWrap anders als das Erstellen der 2 Wrapper wrap_foo und wrap_zoo zu definieren, während ich gerne als Template-Template-Argument direkt foo und zoo verwendet hätte. Gibt es eine Möglichkeit, das zu tun?

#include <iostream> 
#include <utility> 
#include <array> 
using namespace std; 

// boiler plate stuff 

template <template <unsigned J> typename FunWrap, unsigned... Is> 
decltype(auto) get_fun_ptr_aux(std::integer_sequence<unsigned, Is...>, unsigned i) 
{ 
    typedef decltype(&FunWrap<1>::run) FunPtr; 
    constexpr static std::array<FunPtr, sizeof...(Is)> fun_ptrs = { &FunWrap<Is>::run... }; 
    return fun_ptrs[i]; 
} 

template <template <unsigned J> typename FunWrap, unsigned N> 
decltype(auto) get_fun_ptr(unsigned i) 
{ 
    return get_fun_ptr_aux<FunWrap>(std::make_integer_sequence<unsigned, N>{}, i); 
} 

// template functions to be bridged with runtime arguments 
// two functions with same template arguments but different signature 

template <unsigned J> 
void foo() { cout << J << "\n"; } 

template <unsigned J> 
double zoo(double x) { return x + J; } 

// 1 wrapper per each function 

template <unsigned J> 
struct wrap_foo { 
    static void *run() { foo<J>(); } // same signature as foo 
}; 

template <unsigned J> 
struct wrap_zoo { 
    static double run(double x) { return zoo<J>(x); } // same signature as zoo 
}; 

int main() 
{ 
    unsigned index = 5; 
    (*get_fun_ptr<wrap_foo,10>(index))(); 
    cout << (*get_fun_ptr<wrap_zoo,10>(index))(3.5) << "\n"; 
    return 0; 
} 

Antwort

Verwandte Themen