printf函数和fmt函数之间的重载

我有一个类,它在构造函数中接受一组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