Guss
Guss

Reputation: 950

C++ value evaluation in concepts

How to properly evaluate a value in concept declaration / requires clauses ?

Considering a concept is_red which check if a given type has a color static cx member set to /*undefined*/::red, where `/undefined/ in an enum;

template <typename T>
concept is_red = requires(T) {
   { T::color == decltype(T::color)::red };
};

This is obviously wrong, as it only checks if the synthax is well-defined.
Thus, this will not work as expected :

namespace apple {
   enum colors{red, green, yellow };

   struct granny_smith{
      constexpr static auto color = colors::green;
   };
}

static_assert(is_red<apple::granny_smith>); // should fail, but it does not using the previous concept implementation

See live example on godbolt here.

Here is the way I currently evaluate values in concepts :

template <bool condition>
using if_t = std::conditional_t<condition, std::true_type, std::false_type>;

template <typename T>
concept is_red = requires(T) {
   { if_t<(T::color == decltype(T::color)::red)> } -> std::same_as<std::true_type>;
};

Which works fine, but looks a bit odd.

Perhaps there is another - cleaner - way to deal with value evaluation in C++ concepts ?

Upvotes: 0

Views: 846

Answers (1)

Barry
Barry

Reputation: 302862

A concept can take an arbitrary boolean expression on the right-hand side. A requires-expression is just one such boolean expression, but it doesn't have to be that. You can write a comparison directly:

template <typename T>
concept is_red = T::color == decltype(T::color)::red;

Upvotes: 5

Related Questions