可变参数模板函数返回同类型std::tuple的实现问题
问题描述
我有以下用于解析网络二进制数据流的函数,运行正常:
template<typename... Args> inline void Func(char* data) { cout << "unknown" << endl; } template<> inline void Func<int, std::string>(char* data) { int a = *(int*)data; cout << a << endl; } inline void test() { char p[100]; int a = 99; memcpy(p, &a, sizeof(a)); Func<int, int>(p); Func<int, std::string>(p); }
此外,我不仅想输出解析后的值,还希望用tuple返回它们,尝试编写如下代码:
template<typename... Args> inline std::tuple<typename... Args> FuncTuple(char* data) { cout << "unknown" << endl; } template<> inline std::tuple<int, std::string> FuncTuple<int, std::string>(char* data) { std::tuple<int, std::string> t; std::get<0>(t)=*(int*)data; return t; }
但这段代码无法运行,编译器不识别std::tuple<typename... Args>,请问该如何正确编写?
解决方案
你的代码存在两个核心问题:
- 返回类型写法错误:
std::tuple<typename... Args>是冗余写法,可变参数模板参数Args...本身就是类型包,直接写std::tuple<Args...>即可。 - 主模板缺少合法返回值:主模板只执行了输出操作,但没有返回符合
std::tuple<Args...>类型的值,这会导致编译失败。
以下是修正后的代码:
#include <tuple> #include <iostream> #include <cstring> #include <string> using namespace std; template<typename... Args> inline std::tuple<Args...> FuncTuple(char* data) { cout << "unknown" << endl; // 返回默认构造的tuple,保证类型匹配 return std::tuple<Args...>(); } template<> inline std::tuple<int, std::string> FuncTuple<int, std::string>(char* data) { std::tuple<int, std::string> t; // 解析int类型数据 std::get<0>(t) = *(int*)data; // 补充解析std::string的逻辑:假设字符串紧跟在int之后,以'\0'结尾 std::get<1>(t) = std::string(data + sizeof(int)); return t; } inline void test() { char p[100]; int a = 99; const char* str = "hello"; memcpy(p, &a, sizeof(a)); memcpy(p + sizeof(a), str, strlen(str)+1); auto t1 = FuncTuple<int, int>(p); auto t2 = FuncTuple<int, std::string>(p); cout << "tuple<int,int> get<0>: " << get<0>(t1) << endl; cout << "tuple<int,string> get<0>: " << get<0>(t2) << ", get<1>: " << get<1>(t2) << endl; }
额外说明
- 如需处理更多类型组合,可继续添加对应的特化版本。
- 网络数据流解析需注意字节序问题,直接强制类型转换可能在不同架构下出错,建议使用
ntohl/htonl等字节序转换函数处理整数类型。 - 对于
std::string的解析,通常需先读取字符串长度再读取对应内容,示例仅做简单的'\0'结尾字符串处理,实际场景需根据协议调整。
内容的提问来源于stack exchange,提问作者Zhang
相关产品推荐
相关产品推荐

