简体   繁体   中英

Recursive variadic template instation fails

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM