根据参数计数推导可变参数模板

Nik*_*ock 1 c++ templates metaprogramming variadic-templates

想象一下我有两个功能:

void string(const char *str)
{
    std::cout << "this is string" << std::endl;
}

void number(const char *str, double f)
{
    std::cout << "this is number" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我想编写一个通用包装器,以便能够format()像这样调用:

int main() {
    format("single arg");
    format("format string", 1.0);
    format("single arg", "format string", 1.0);
    format("format string 1", 1.0, "just string arg", "format string 2", 2.0);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

也就是说,如果参数以 {string, number} 对的形式出现,则调用number(); 否则请致电string(). 显然,只能从右到左解包参数。我尝试按照以下(错误)方式实现它:

template<class T>
void operation(T first)
{
    string(first);
}

template<class T, class U = float>
void operation(T first, U second)
{
    number(first, second);
}

template<class ... ARGS>
void format(ARGS ... args)
{
    auto last = (args, ...);
    using last_type = typename decltype(last);
    if constexpr (std::is_arithmetic_v<last_type>)
        (..., operation(args, last));
    else
        (..., operation(args)); 
}
Run Code Online (Sandbox Code Playgroud)

问题是,在打开包装时,operation(args, last)我们会同时得到argslast漂浮物。我相信有一些简单的方法可以实现我想要的(不依赖元组等)。

Que*_*tin 5

这是仅使用重载解析的概念验证。不过,我不确定它的可扩展性如何。

void format() {}

void format(char const *str) {
    string(str);
}

template <class... Args>
void format(char const *str, char const *nextStr, Args... args);

template <class... Args>
void format(char const *str, double f, Args... args);

template <class... Args>
void format(char const *str, char const *nextStr, Args... args) {
    string(str);
    format(nextStr, args...);
}

template <class... Args>
void format(char const *str, double f, Args... args) {
    number(str, f);
    format(args...);
}
Run Code Online (Sandbox Code Playgroud)

在 Godbolt.org 上观看直播