Home > Software engineering >  How to define a C concept that a type is same_as any one of several types?
How to define a C concept that a type is same_as any one of several types?

Time:08-17

I would like to define a concept that indicates a type is one of several supported types. I can do this by repeatedly listing the types with std::same_as<U>:

#include <concepts>

template <typename T>
concept IsMySupportedType = std::same_as<T, int32_t> || std::same_as<T, int64_t> || std::same_as<T, float> || std::same_as<T, double>;

Is there a more concise way to write this without repeating the std::same_as concept?

CodePudding user response:

This can be done using a variadic helper concept (taken from the cppreference for std::same_as):

template <typename T, typename... U>
concept IsAnyOf = (std::same_as<T, U> || ...);

This can be used to define the desired concept as follows:

template <typename T>
concept IsMySupportedType = IsAnyOf<T, std::int32_t, std::int64_t, float, double>;

Note that the initial T on the right-hand side is important.

The resulting concept can be used as expected:

static_assert(IsMySupportedType<float>);
static_assert(!IsMySupportedType<std::int8_t>);

Compiling example: https://godbolt.org/z/6dE9r1EY6

CodePudding user response:

I would use std::disjunction which has the upside that it is short-circuiting:
"if there is a template type argument Bi with bool(Bi::value) != false, then instantiating disjunction<B1, ..., BN>::value does not require the instantiation of Bj::value for j > i"

template <class T, class... U>
concept any_of = std::disjunction_v<std::is_same<T, U>...>;

template <class T>
concept IsMySupportedType = any_of<T, std::int32_t, std::int64_t, float, double>;

Demo

  • Related