我有一个类,它在构造函数中接受一组C printf变量参数,如下所示:
class Foo {
public:
Foo(const char* str, ...) __attribute__((format(printf, 2, 3)));
现在我希望能够在这个类中使用fmt library。如果我愿意改变所有的调用者,我可以像这样改变它:
class Foo {
public:
template<typename Str, typename... Args>
Foo(const Str& str, const Args&... args)
: Foo(str, fmt::make_args_checked<Args...>(str, args...))
{}
private:
Foo(fmt::string_view fmt, fmt::format_args args);
但是这个类被用在100多个地方,“改变世界”是不可行的。所以我想保留这两个构造器,但显然现在我需要一种在它们之间进行选择的方法。我对不得不添加一个新的伪参数或其他东西并不感到兴奋。
然后我想,嗯,我真的想强制使用printf宏,因为我的printf样式的代码利用了FMT_STRING()
和clang中的printf格式检查。因此,也许我可以这样做:我可以创建自己的宏,例如MYFMT()
,它将以某种方式调用FMT_STRING(),或者至少执行相同的检查,但然后解析为我自己的类型,可以用来选择不同的构造函数;例如:
#define MYFMT(_f) ...
class Foo {
public:
Foo(const char* str, ...);
Foo(const MyType& str, ...) ...
因此,其用法类似于:
auto x = Foo("this is a %s string", "printf");
auto y = Foo(MYFMT("this is a {} string"), "fmt");
但我已经尝试了几个小时,并试图弄清楚FMT_STRING宏是如何工作的,以及我需要做什么,但我什么也想不出来。也许由于某种原因,这是不可能的,但如果有人有任何提示,那就太好了。
我的基础编译器是GCC 10,clang 9和MSVC2019,所以我至少可以依赖C++17。
转载请注明出处:http://www.intrusion-fire.net/article/20230526/2608988.html