Search code examples
c++c++11variadic

Dynamically creating and expanding std::tuple into parameter pack


I'm writing a plugin for software written in C++, here's a snippet where the plugin is defined:

extern "C"
irods::ms_table_entry* plugin_factory() {

    // The number of msParam_t* arguments that it will accept
    int numArguments = 2;

    irods::ms_table_entry* msvc = new irods::ms_table_entry(numArguments); 

    msvc->add_operation(
        "my_microservice",
        std::function<int(msParam_t*, msParam_t*, ruleExecInfo_t*)>(MyMicroservice)
    ); 

    return msvc;
}  

I'd like to be able to use numArguments to dynamically generate the std::function<int(msParam_t*, msParam_t*, ruleExecInfo_t*)> parameter pack. Where numArguments represents the number of msParam_t* arguments.

I'm not a C++ expert (especially with templating), so after some research I've found that this might be possible by implementing the following:

  • std::tuple
  • std::tuple_cat
  • std::index_sequence
  • std::make_integer_sequence

But I don't really know how to get started on implementing this. The examples I found were hard to understand, and I couldn't manage to translate them into my own needs. Can anyone provide tips, short examples, or references on how this might work? Any info is greatly appreciated!


Solution

  • I don't know if the following is exactly what you're asking but I think that what you want is being able to generate the right template parameters for the std::function based on the number of arguments that your MyMicroservice takes which is stored into the numParameters variable.

    If that is the case you can simply omit writing them at all and use decltypeand let the compiler write them for you.

    int myMicroservice1(int a,int b, int c){
        return a+b+c;
    }
    
    int myMicroservice2(int a,int b, int c,int d){
        return a*b*c-d;
    }
    
    int myMicroservice3(int a,int b, int c,int d,int e, int f){
        return a*b*c+e+f;
    }
    
    
    template<typename... types_t>
    void add_operation(const std::string & _op, std::function< int(types_t...)> _f ){
    
    }   
    
    int main() {
        add_operation("blabla",std::function<decltype(myMicroservice1)>(myMicroservice1));
        add_operation("blabla",std::function<decltype(myMicroservice2)>(myMicroservice2));
        add_operation("blabla",std::function<decltype(myMicroservice3)>(myMicroservice3));
        return 0;
    }