Phillip
Phillip

Reputation: 135

Applying a function to all template parameters

I'm trying to make a function that finds an element by id and deletes it from static vectors in some types.

template<typename First>
void RemoveComponentByID(EntityID ID)
{
    auto element = binary_find(First::Array.begin(), First::Array.end(), ID);
    First::Array.erase(element);
}

template<typename First, typename... Rest>
void RemoveComponentByID(EntityID ID)
{
    auto element = binary_find(First::Array.begin(), First::Array.end(), ID);
    First::Array.erase(element);
    RemoveComponentByID<Rest...>(ID);
}

But when I call the function RemoveComponentByID<Vector3s,Textures>(id); The error " 'RemoveComponentByID' : ambiguous function call to overloaded function" pops up. Why is that?

Upvotes: 1

Views: 52

Answers (1)

Jarod42
Jarod42

Reputation: 217418

For overload resolution, there is a tie breaker between

  • template <typename T> void foo(T);
  • template <typename T, typename ...Ts> void foo(T, Ts...);

in favour to the non variadic, but it is not the cas when those template are not part of function argument as you.

So, neither of

  • template <typename T> void bar();
  • template <typename T, typename ...Ts> void bar();

is more specialized, thus the ambiguous call for bar<SomeType>().

You might do (C++17):

template<typename First, typename... Rest>
void RemoveComponentByID(EntityID ID)
{
    auto element = binary_find(First::Array.begin(), First::Array.end(), ID);
    First::Array.erase(element);
    if constexpr (sizeof...(Rest) > 0) {
        RemoveComponentByID<Rest...>(ID);
    }
}

or, without recursion:

template<typename T>
void RemoveComponentByIDImpl(EntityID ID)
{
    auto element = binary_find(T::Array.begin(), T::Array.end(), ID);
    T::Array.erase(element);
}

template<typename... Ts>
void RemoveComponentByID(EntityID ID)
{
    (RemoveComponentByIDImpl<Ts>(ID), ...);
}

Upvotes: 1

Related Questions