2017-06-06 76 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); 
    } 

這將在一個元組調用給定函數的每個元素。