c++ 将元组转换为可变参数

rwqw0loc  于 2023-01-28  发布在  其他
关注(0)|答案(2)|浏览(116)

我不确定我想要实现的是什么,但是我需要我的模板函数(my_func)能够同时接受变量参数和元组参数,代码注解中有更清楚的描述。

struct A{
    static void call_func(int a, std::string b) {
        std::cout<<"int is: "<<a<<", string is: "<<b<<"\n";
    }
};

struct B{
    static void call_func(std::string a, std::string b) {
        std::cout<<"string is: "<<a<<", string is: "<<b<<"\n";
    }
};

struct C{
    static void call_func(int a) {
        std::cout<<"int is: "<<a<<"\n";
    }
};

template<typename T, typename... Args> 
void my_func(Args... args) {
    T::call_func(args...);
}

int main() {

    my_func<A>(3, "ant");    //int is: 3, string is: ant
    my_func<B>("bat", "bee");  //string is: bat, string is: bee
    my_func<C>(5);  //int is: 5

    //Is there a way to call(or modify) my_func such that it also accepts a tuple
    std::tuple<int, std::string> a_params{3,"tuple-ant"};
    std::tuple<std::string, std::string> b_params{"tuple-bat","tuple-bee"};
    std::tuple<int> c_params{7};
    // my_func<A>(a_params); 
    // my_func<B>(b_params);
    // my_func<C>(c_params);   
 
}
q5lcpyga

q5lcpyga1#

您确定将两个函数都命名为my_func()是个好主意吗?为了避免混淆,第二个函数命名为my_func_tuple()或类似的名称如何?
总之...在我看来你要找的是std::apply()使用它,元组版本可以被写为

template <typename T, typename ... Args>
void my_func(std::tuple<Args...> tpl) {
  std::apply(T::call_func, tpl);
}

考虑到std::apply()从C17开始就可用;在C17之前(C11和C14),必须使用整数序列模拟它;请看“哞叫鸭”的回答。

qyswt5oh

qyswt5oh2#

这几乎就是integer_sequence的用途:

template<typename T, typename... Args, std::size_t... ints> 
void my_func(std::tuple<Args...> args, std::integer_sequence<std::size_t,ints...> sequence) {
    T::call_func(std::get<ints>(args)...);
}

std::get<ints>(args)...表示对于size_t...ints模板参数中的每一项,调用get<ints>(args)。这允许您将args解压缩为方法的参数列表。但随后我们必须弄清楚如何生成正确的integer_sequence。幸运的是,这也很容易:

template<typename T, typename... Args> 
void my_func(std::tuple<Args...> args){
    my_func<T, Args...>(args, std::make_index_sequence<sizeof...(Args)>{});
}

http://coliru.stacked-crooked.com/a/1dfdb24d5d21c756

相关问题