带有 sizeof ... (args) == 0 参数包的函数,因为基本情况无法编译

Function with parameter pack with sizeof ... (args) == 0 as base case doesn't compile

这是我的函数代码:

#include <iostream>
#include <type_traits>
#include <algorithm>

template <typename Head, typename ... Args>
std::common_type_t<Head, Args...> mx(Head n, Args ... args)
{
    if (sizeof ... (args) == 0)
        return n;
    else
        return std::max(n, mx(args ...));
}

int main()
{
    std::cout << mx(3, 4, 5);
}

我遇到了编译错误:

main.cpp: In instantiation of 'std::common_type_t<Head, Args ...> mx(Head, Args ...) [with Head = int; Args = {}; std::common_type_t<Head, Args ...> = int]': main.cpp:11:24:
recursively required from 'std::common_type_t<Head, Args ...> mx(Head, Args ...) [with Head = int; Args = {int}; std::common_type_t<Head, Args ...> = int]' main.cpp:11:24: required from 'std::common_type_t<Head, Args ...> mx(Head, Args ...) [with Head = int; Args = {int, int}; std::common_type_t<Head, Args ...> = int]' main.cpp:16:25: required from here main.cpp:11:24: error: no matching function for call to 'mx()' 11 | return std::max(n, mx(args ...)); | ~~^~~~~~~~~~ main.cpp:6:35: note: candidate: 'template<class Head, class ... Args> std::common_type_t<Head, Args ...> mx(Head, Args ...)' 6 | std::common_type_t<Head, Args...> mx(Head n, Args ... args) | ^~ main.cpp:6:35: note: template argument deduction/substitution failed: main.cpp:11:24: note: candidate expects at least 1 argument, 0 provided 11 | return std::max(n, mx(args ...)); | ~~^~~~~~~~~~

当然我可以写得更妥当,像这样:

template <typename Head>
std::common_type_t<Head> mx(Head n)
{
    return n;
}

template <typename Head, typename ... Args>
std::common_type_t<Head, Args...> mx(Head n, Args ... args)
{
    return std::max(n, mx(args ...));
}

但是,我仍然不明白为什么我的第一个选项不起作用。从错误判断,即使参数包中没有参数,它也会以某种方式尝试调用函数的递归版本。但这对我来说没有任何意义,因为我考虑过这个案例。有什么问题,我可以解决吗?

即使

if (sizeof ... (args) == 0)

整个函数必须是格式正确的 C++。

    return std::max(n, mx(args ...));

这仍然必须是有效的 C++,即使不会被执行。如果在模板上下文之外,你有一个 if (1)else 部分必须仍然是有效的 C++,你不能只是把随机生成的乱码扔进去,这是一回事。当 sizeof...(args) 为 0 时,函数调用变为 mx(),当然,没有有效的重载。

您想要做的是使用 if constexpr 而不是普通的 if

if constexpr (sizeof ... (args) == 0)