如果您将代码减少为:
Sum<int>();
您会收到更有用的错误消息:
31 : <source>:31:16: error: call to 'Sum' is ambiguous
auto sum = Sum<int>();
^~~~~~~~
17 : <source>:17:9: note: candidate function [with Arg = int, Args = <>]
int32_t Sum()
^
24 : <source>:24:9: note: candidate function [with Arg = int]
int32_t Sum()
^
1 error generated.
因此,很明显,第一个重载与Args = <>
和第二个。两者都是可行的。
人们可能会认为这是一种解决方案的专业化:
template <typename Arg>
int32_t Sum<Arg>()
{
return CodeByType<Arg>::Value;
}
如果标准允许的话,这确实可以解决问题。不允许部分函数特化。
C++17解决方案:
这是最优雅的解决方案:
常量表达式 if http://en.cppreference.com/w/cpp/language/if#Constexpr_If救援:
template <typename Arg, typename... Args>
int32_t Sum()
{
if constexpr(sizeof...(Args) == 0)
return CodeByType<Arg>::Value;
else
return Sum<Arg>() + Sum<Args...>();
}
C++14解决方案
我们使用 SFINAE 来启用/禁用我们想要的功能。请注意,函数定义顺序必须颠倒。
template <typename Arg, typename... Args>
auto Sum() -> std::enable_if_t<(sizeof...(Args) == 0), int32_t>
{
return CodeByType<Arg>::Value;
}
template <typename Arg, typename... Args>
auto Sum() -> std::enable_if_t<(sizeof...(Args) > 0), int32_t>
{
return Sum<Arg>() + Sum<Args...>();
}
C++11解决方案
只需更换std::enable_if_t<>
with typename std::enable_if<>::type