Search code examples
c++algorithmc++17variadic-templates

Efficient variadic equals-any function


I want to make a function that returns whether the first parameter equals any of the others. This is what I came up with:

template<typename T, typename... U>
bool equalsAny(T first, U... args) {
    U arr[] {args...};
    for (auto& arg : arr) if (first == arg) return true;
    return false;
}

This is of course very slow in the sense that an array must be created for all arguments. Is there any way to make this almost as fast as first == arg1 || first == arg2 || ... by for instance using c++17 fold expressions?


Solution

  • You tagged C++17 so... what's wrong with template folding ?

    template <typename T, typename... U>
    bool equalsAny (T first, U... args)
     { return (first == args || ...); }
    

    Pre C++17, you can use the initialization of an unused C-style array (I'm not an expert but I suppose that a good compiler can optimize it very well)

    template <typename T, typename... U>
    bool equalsAny (T first, U... args)
     { 
       using unused = bool[];
    
       bool ret { false };
    
       (void)unused { false, (ret = ret || (first == args))... };
    
       return ret;
    }