check variadic templates parameters for uniqueness

Passing a pointer to base_all<U...> merely requires the existence of a declaration of base_all<U...>. Without attempting the to access the definition, the compiler won’t detect that the type is actually ill-defined. One approach to mitigate that problem would be to use an argument which requires a definition of base_all<U...>, e.g.:

template< class ...T> struct base_all
   : id<T> ...
{
    typedef int type;
};
// ...
template< class ... U>
static constexpr bool test(typename base_all<U...>::type) noexcept
{
    return true;
}

Although the above answers the question, it fail to compile: the multiple inheritance created isn’t in a suitable context to be considered for SFINAE. I don’t think you can leverage the rule on not allowing the same base inherited from twice. The relevant test can be implemented differently, though:

#include <type_traits>

template <typename...>
struct is_one_of;

template <typename F>
struct is_one_of<F>
{
    static constexpr bool value = false;
};

template <typename F, typename S, typename... T>
struct is_one_of<F, S, T...>
{
    static constexpr bool value = std::is_same<F, S>::value
        || is_one_of<F, T...>::value;
};

template <typename...>
struct is_unique;

template <>
struct is_unique<> {
    static constexpr bool value = true;
};

template<typename F, typename... T>
struct is_unique<F, T...>
{
    static constexpr bool value = is_unique<T...>::value
        && !is_one_of<F, T...>::value;
};

int main()
{
    constexpr bool b = is_unique<int, float, double>::value;
    constexpr bool c = is_unique< int, char, int>::value;
    static_assert( b == true && c == false , "!");
}

Leave a Comment