在 中fmt/core.h,我注意到该函数使用带有给定谓词的count_named_args()模板函数。count
我发现版本的重载版本count很奇怪:
template <bool B1, bool B2, bool... Tail> constexpr auto count() -> size_t {
return (B1 ? 1 : 0) + count<B2, Tail...>();
}
Run Code Online (Sandbox Code Playgroud)
为什么我们需要使用模板参数bool B2来显式提取下一个布尔值,而不是直接使用参数包bool... Tail?
如果我删除这些bool B2内容,然后尝试编译:
template <bool B1, bool... Tail> constexpr auto count() -> size_t {
return (B1 ? 1 : 0) + count<Tail...>();
}
Run Code Online (Sandbox Code Playgroud)
static_assert(count<false>() == 0);
static_assert(count<true, false>() == 1);
Run Code Online (Sandbox Code Playgroud)
当参数数量减少到最后一个时,它会给出一个错误,因为确定重载是不明确的:
size_t count<false,>(void) noexcept
size_t count<false>(void) noexcept
Run Code Online (Sandbox Code Playgroud)
查看当前的 main,有两个函数模板:
template <bool B = false> constexpr auto count() -> size_t { return B ? 1 : 0; }
template <bool B1, bool B2, bool... Tail> constexpr auto count() -> size_t {
return (B1 ? 1 : 0) + count<B2, Tail...>();
}
Run Code Online (Sandbox Code Playgroud)
如果那些是
template <bool B = false> constexpr auto count() -> size_t { return B ? 1 : 0; }
template <bool B1, bool... Tail> constexpr auto count() -> size_t {
return (B1 ? 1 : 0) + count<Tail...>();
}
Run Code Online (Sandbox Code Playgroud)
然后对于 call count<false>(),两个候选者都会被考虑,并且根据重载解析规则,两者都不比另一个更专业 -> 歧义。请记住,参数包可以为空。为什么有一个额外的参数包不被认为不那么专业,我真的不知道。
仅具有<bool B1, bool... Tail>不适用于零参数,并且count对于这种情况具有额外的非模板不适用于count<pack...>()和pack为空的极端情况。另一方面,由于默认值,<bool B = false>仍然可以像这样调用。count()
我认为<bool B = false>and<bool B1, bool B2, bool... Tail>是最通用、最简单的解决方案。