带有 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)
这是我的函数代码:
#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)