我正在尝试转换一些代码,以便它也在gcc上编译(现在,它仅在MSVC上编译).
我坚持的代码是伪格式化函数,它接受一个格式字符串和零个或多个参数(const char *format, ...)作为输入.然后它将处理一些占用一些参数的占位符,并将其余的传递给vsprintf动态生成的新va_list.
这是生成新的实际代码va_list:
char *new_args = (char *) malloc(sum);
char *n = new_args;
for(int i = 0; i < nArgs; i++)
{
int j = order[i];
int len = _getlen(types[j]);
memcpy(n, args + cumulOffsets[j], len);
n += len;
}
vsprintf(buffer, sFormat.c_str(), new_args);
Run Code Online (Sandbox Code Playgroud)
在我的辩护中,我没有,也绝不会写这段代码.事实上,我认为这是我一生中见过的最讨厌的事情之一.
但是,这个功能非常复杂,非常老,而且非常重要.它也没有被修改多年(好吧,除了现在),所以虽然我想从头开始重写它,我无法证明它需要花费的时间加上它会引入的错误.
所以,我需要一种方法在GCC上做同样的事情..但是有一个va_list不是char *我得到的:
error: ISO C++ forbids casting to an array type '__va_list_tag [1]'
该FastFormat库的工作原理是这样的:
string example;
fastformat::fmt(example, "I am asking {0} question on {1}", 1, "stackoverflow");
Run Code Online (Sandbox Code Playgroud)
它还声称"100%类型安全".我可以理解其他库如何boost::format通过重载实现这operator%一点,我也经常使用我的代码.
但是,如果我能够使用逗号,那么对其他程序员来说就不那么令人惊讶了.我真的很想知道如何在没有模板操作符重载技巧的情况下保证类型安全.
除了注意:如果你想知道什么是"模板化运算符重载技巧",这就是boost :: format的工作原理(主要是):
struct Test
{
template<class T>
Test& operator%(const T& what) { cout << what << "\n" /* Example */; return *this; }
};
Test() % 5 % "abc";
Run Code Online (Sandbox Code Playgroud)