c++templatesc++17variadic-templatesfold-expression

Checking if variadic template parameters are unique using fold expressions


Given a variadic template parameter pack, I want to check if all types given to it are unique using an inline constexpr bool and fold expressions. I tried something like this:

template<class... T>
inline static constexpr bool is_unique = (... && (!is_one_of<T, ...>));

Where is_one_of is a similar bool that works correctly. But this line doesn't compile regardless of what I put into is_one_of. Can this even be done using fold expressions, or do I need to use a regular struct for this purpose?


Solution

  • You approach doesn't really work because is_one_of needs to be called with a type T and all the remaining types not including T. There's no way of expressing that with a fold expression over a single parameter pack. I suggest using specialization instead:

    template <typename...>
    inline constexpr auto is_unique = std::true_type{};
    
    template <typename T, typename... Rest>
    inline constexpr auto is_unique<T, Rest...> = std::bool_constant<
        (!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
    >{};   
    

    Usage:

    static_assert(is_unique<>);
    static_assert(is_unique<int>);
    static_assert(is_unique<int, float, double>);
    static_assert(!is_unique<int, float, double, int>);
    

    live example on wandbox.org


    (Thanks to Barry for the simplification that uses a fold expression.)