c++ - C++11: how to write a template function that works like get<tuple>... but receives param pack? -


i know in c++11, get<> template function works std::tuple indexed value of tuple, resolved @ compile time.

but requirement have template function called get<> receives parameter pack, code should below:

#include<iostream> using namespace std; template<typename head, typename ... tail> auto get(size_t index, head&& t, tail&&...tail){     return get(index-1, tail...); } template<typename head, typename ... tail> head get<0>(head&& t, tail&&...tail){     return t; } int main(){     cout<<get(3,"abc",'x',27,"hello")<<endl;     cout<<get(2,"abc",'x',28,"hello")<<endl;     return 0; } 

well doesn't compile, sure, don't know how write such "get" template function. wish main function run , print below:

hello 28 

so question: how implement "get" template mentioned above? thanks!

do really need able select index @ runtime? if not, following should enough:

template <std::size_t index, typename ...p> auto get(p &&... params) {     return std::get<index>(std::make_tuple(params...)); }  // ...  std::cout << get<1>("abc", 42, 123.456); // prints 42 

if indeed want have index normal (runtime) parameter, you'd have return std::variant<p...> (or std::any, or tagged union), since return type can't depend on runtime parameter.

a possible implementation this:

template <typename ...p> std::variant<p...> get(std::size_t index, p &&... params) {     std::size_t pos = 0;     std::variant<p...> ret;     ((index == pos++ ? void(ret = params) : void()) , ...);     return ret; }  // ...  std::cout << std::get<int>( get(1, "abc", 42, 123.456) ); // prints 42 too, looks ugly 

or specify return type template parameter:

template <typename t, typename ...p> t get(std::size_t index, p &&... params) {     std::size_t pos = 0;     std::variant<p...> va;     ((index == pos++ ? void(va = params) : void()) , ...);     if (t *ptr = std::get_if<t>(va))         return t;     else         throw /*something*/; }  // ...  std::cout << get<int>(1, "abc", 42, 123.456); // 42 

or pass value function/functor instead: (thanks @yakk)

template <typename t, typename ...p> void get(std::size_t index, t &&func, p &&... params) {     std::size_t pos = 0;     ((index == pos++ ? void(func(params)) : void()) , ...); }  // ...  get(1, [](int x){std::cout << x;}, "abc", 42, 123.456); // 42 // alternative: // get(1, [](auto x){std::cout << x;}, "abc", 42, 123.456); // 42 too,  // print type can printed without having  // specify type manually. 

Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -