2017-06-06 47 views
0

我写了C++编写的软件插件,这里的地方插件定义一个片段:动态创建和扩展的std ::元组为参数包

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; 
} 

我想成为能够使用numArguments动态生成std::function<int(msParam_t*, msParam_t*, ruleExecInfo_t*)>参数包。其中numArguments表示参数msParam_t*的数量。

我不是一个C++专家(尤其是与模板),所以after some research我发现这个可能通过实施可以如下:

  • 的std ::元组
  • STD: :tuple_cat
  • 的std :: index_sequence
  • 的std :: make_integer_sequence

但我真的不知道如何开始实施这个。我发现的例子很难理解,我无法将它们转化为我自己的需求。任何人都可以提供关于如何工作的提示,简短示例或参考资料吗?任何信息非常感谢!

+1

是在编译时已知的numArgument吗? –

+0

它不可能动态执行此操作,因为这将涉及代码生成,但可以静态或静态生成它。什么是add_operation类型? – user1937198

+0

@DavideSpataro - 否,将在运行时定义'numArgument'。 –

回答

1

我不知道以下内容是否正是你所要求的,但我认为你想要的是能够基于MyMicroservice所需的参数数量为std::function生成正确的模板参数,这是存入numParameters变量。

如果是这种情况,您可以简单地省略编写它们并使用decltype并让编译器为您编写它们。

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; 
} 
+0

我刚刚意识到,即使我可以从运行时整数动态构建参数包,“MyMicroservice”参数仍然是静态的。要求为每组不同的参数定义一个函数。我很感谢你的回答,它帮助我找出了我的想法中的缺陷。 –

0
template<typename T> 
struct toFunc; 

template<typename...T> 
struct toFunc<std::tuple<T...>> 
{ 
    using type = std::function<void(T...)>; 
}; 

int main(int argc, char **argv) { 

    using t = std::tuple<int, int, int>; 
    using func = toFunc<t>::type; 
    auto f = func([](int a, int b, int c){std::cout << a << b << c << std::endl;}); 
    f(1, 2, 3); 
    return 0; 
} 

toFunc typetrait会将您的元组转换为函数类型。不知道你是否想要。如果你想用参数来调用你也许需要寻找 http://en.cppreference.com/w/cpp/utility/apply

,或者你可以使用这个实现:

namespace detail 
{ 
      template <unsigned int N> 
      struct for_each_t_idx 
      { 
       template <template<std::size_t> class Functor, typename... ArgsT> 
       static void exec(const std::tuple<ArgsT...>& t, Functor<N> func) 
       { 
        for_each_t_idx<N - 1>::exec(t, func); 
        func<N - 1>(t); 
       } 
      }; 

      template <> 
      struct for_each_t_idx<0> 
      { 
       template <template<std::size_t> class Functor, typename... ArgsT> 
       static void exec(const std::tuple<ArgsT...>& t, Functor<0> func) 
       { 
       } 
      }; 
} 

    template <template<std::size_t> class Functor, typename... ArgsT> 
    void for_each_idx(const std::tuple<ArgsT...>& t, Functor<sizeof...(ArgsT)> func) 
    { 
     detail::for_each_t_idx<sizeof...(ArgsT)>::exec(t, func); 
    } 

这将在一个元组调用给定函数的每个元素。