Reputation: 950
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
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