What is the reason, that in the following example the instantiaton with three int is working with the second function template but not with the first one. Additional: with the types State1 / State1 it isn't working either.
struct State1{};
struct State2{};
#if 0
template<typename none = void>
constexpr void f()
{
}
template<typename First, typename... Rest>
constexpr void f()
{
f<Rest...>();
}
#else
template<typename none = void>
constexpr void f()
{
}
template<int First, int... Rest>
constexpr void f()
{
f<Rest...>();
}
#endif
void test()
{
f<1, 2, 3>();
// f<State1, State2>();
}
Thank you any hints!
The problem in the first case is that both template specializations match when you pass a single template parameter (a parameter pack can be empty), so the overload set contains more than one candidate. You can use SFINAE to make the second one fail to instantiate:
#include <type_traits>
struct State1{};
struct State2{};
template<typename none = void>
constexpr auto f() -> void
{
}
template<typename First, typename... Rest>
constexpr auto f() -> std::enable_if<sizeof...(Rest), void>::type
// This will not instantiate when the parameter pack is empty
// And the overload set will contain only the candidate above
{
f<Rest...>();
}
int main()
{
f<State1, State2>();
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.