Search code examples
c++c++20variadic-templatestype-traitsc++-concepts

C++ concept that checks there are no repeating types in a variadic template


I'm trying to figure out how to write a conecpt that checks that there are no repeated types in a variadic template.

I'm aware I can't call a concept recursively within itself, but if I could my solution would look something like this (ignoring the lack of stop condition):

#include <concepts>

template <class TYPE, class ... TYPE_LIST>
concept is_not_in_list = ((!std::same_as<TYPE, TYPE_LIST>) && ...);

template <class FIRST_TYPE_IN_LIST, class ... REST_OF_TYPE_LIST>
concept is_non_repeating_list_ = (_type_not_in_list_<FIRST_TYPE_IN_LIST, REST_OF_TYPE_LIST> && is_non_repeating_list<REST_OF_TYPE_LIST>);

// Usage

template<is_non_repeating_list ... TYPE_LIST>
class MyClass {}

I can't find a type traits or concepts in the standard library to help me solve this yet. Any thoughts?


Solution

  • This was pitched in a comment with a link to anotehr SO post...

    check variadic templates parameters for uniqueness

    What I deam the cleanest solution of the many I've read so far (thanks all for your suggestions!), is to use type traits to achieve the recursive part that I couldn't achieve directly with concepts like so:

    template<typename T, typename... Types>
    constexpr bool are_types_unique_v = (!std::is_same_v<T, Types> && ...) && are_types_unique_v<Types...>;
    
    template<typename T>
    constexpr bool are_types_unique_v<T> = true;
    

    And then use that to define the now quite simple concept:

    template <class TYPE_LIST>
    concept are_types_unqiue = (are_types_unique_v<TYPE_LIST>);