C++20如何将参数包编码为变量供可变参数函数使用?
在C++20中不使用va_list实现可变参数的编码传递与解码调用类printf函数
我在C++20中摸索了很久,不确定是否能实现以下需求,特来提问:
能否不依赖C语言的va_list,完成以下操作:
- 将可变参数函数模板接收的任意参数列表编码为单个变量;
- 将该变量传递给一个非模板函数;
- 在这个非模板函数中解码该变量,最终将参数传递给类printf风格的函数?
期望能写出类似如下的代码:
/* * main.cpp */ #include <very_old_library.h> #include <utility> typedef /*** 这里应该定义什么类型? ***/ AmazingVariadicArgumentEncoderType; /* Impl26() 不是模板函数,接受固定数量的参数 */ void Impl26(const char *fmt, AmazingVariadicArgumentEncoderType encodedArgs) { /* * 在这里解码 encodedArgs,得到 decodedArgs(可能?) */ VeryOldLibraryFunctionWithPrintfSemantics(fmt, decodedArgs... /* 不确定这里该用什么语法 */); } template <typename... Args> void Wrapper(const char *fmt, Args&&... args) { AmazingVariadicArgumentEncoderType encodedArgs; encodedArgs = /* * 在这里编码 args,得到 encodedArgs。 * * 可能需要用到: * std::forward<Args>(args) ... * ? */ Impl26(fmt, encodedArgs); } int main(int argc, char *argv[]) { // 以下都是 Wrapper() 的合法调用 Wrapper(kOpaqueSecretString1, -123); Wrapper(kOpaqueSecretString2, "jenny", 8675309, 'q', argv[1]); Wrapper(kOpaqueSecretString3); return 0; } /* * very_old_library.h */ const char *kOpaqueSecretString1; const char *kOpaqueSecretString2; const char *kOpaqueSecretString3; void VeryOldLibraryFunctionWithPrintfSemantics(const char *fmt, ...);
(上述代码是实际问题的简化版本)
我找不到合适的AmazingVariadicArgumentEncoderType定义,也不清楚具体的编解码步骤。
换个更清晰的说法:如何编写一个接受单个参数的非模板函数,把这个参数拆解成多个参数传递给类printf风格的函数?
以下是我已经考虑过但不适用的方案:
- 使用
std::format或std::iostream/std::cout:实际场景不是输出到stdout,必须对接使用C风格可变参数的类printf库API,且该库无法替换; - 将
Impl26()改为函数模板:实际代码中它是虚成员函数,没法模板化; - 引入
<stdarg.h>:虽然能用C风格可变参数,但出于实验和学习目的,希望避免使用; - 编码为
std::tuple:没办法在不模板化Impl26()的前提下传递任意类型的tuple; - 重写类printf函数的格式字符串解析逻辑:希望直接透传参数,不想猜测底层库的实现细节。
内容的提问来源于stack exchange,提问作者pion
相关产品推荐
相关产品推荐

