如何向std::tuple传递参数包?
向std::tuple传递参数包的正确方式
你的代码报错的核心原因有两个:
- 直接声明模板化的全局变量
template <typename... Args> std::tuple <Args...> footup;是无效的,C++要求模板变量必须经过实例化才能使用,编译器无法自动推断这个全局tuple的类型。 - 函数模板
bar的参数中,std::tuple<Args...>&与Args... args的模板参数绑定,调用时编译器无法同时从无类型的footup和参数包推断出一致的Args类型,从而抛出missing template arguments before token错误。
修正方案一:明确指定全局tuple的类型
直接给全局footup指定具体的模板参数,让编译器明确其类型:
#include <tuple> #include <iostream> // 明确指定tuple包含7个int类型元素 std::tuple<int, int, int, int, int, int, int> footup; template <typename... Args> void bar(std::tuple<Args...>& footup, Args... args) { footup = std::make_tuple(args...); } int main() { bar(footup, 1, 2, 3, 4, 5, 6, 7); std::cout << std::get<0>(footup) << " " << std::get<1>(footup) << " " << std::get<2>(footup) << "\n\n"; return 0; }
修正方案二:让函数返回tuple(更简洁)
避免使用全局模板变量,直接让bar函数根据参数包创建并返回tuple,用auto自动推断变量类型:
#include <tuple> #include <iostream> template <typename... Args> std::tuple<Args...> bar(Args... args) { return std::make_tuple(args...); } int main() { auto footup = bar(1, 2, 3, 4, 5, 6, 7); std::cout << std::get<0>(footup) << " " << std::get<1>(footup) << " " << std::get<2>(footup) << "\n\n"; return 0; }
修正方案三:调整函数模板的参数推断逻辑(C++14及以上)
如果必须保留全局变量的模板化声明,可以通过将tuple的类型与参数包分离,让编译器先从参数包推断类型,再初始化tuple:
#include <tuple> #include <iostream> // 声明模板变量(C++14及以上支持) template <typename... Args> std::tuple<Args...> footup; template <typename... Args> void bar(Args... args) { // 明确实例化模板变量 footup<Args...> = std::make_tuple(args...); } int main() { bar(1, 2, 3, 4, 5, 6, 7); // 使用时也需要明确指定模板参数 std::cout << std::get<0>(footup<int, int, int, int, int, int, int>) << " " << std::get<1>(footup<int, int, int, int, int, int, int>) << " " << std::get<2>(footup<int, int, int, int, int, int, int>) << "\n\n"; return 0; }
内容的提问来源于stack exchange,提问作者Ashley Ben Story
相关产品推荐
相关产品推荐

