Home > Software engineering >  Can a concept satisfaction of an expression, contains both type and the reference?
Can a concept satisfaction of an expression, contains both type and the reference?

Time:11-23

Is there a way to make the following code not so bloated?

I mean join both type and a reference somehow (|| does not work).

template<typename T>
concept IntegralVector = std::integral<typename T::value_type> &&
requires(T t)
{
    { t.size() } -> std::convertible_to<std::size_t>;
}
&& (requires(T t)
{
    { t[0] } -> std::same_as<typename T::value_type&>;
} || requires(T t)
{
    { t[0] } -> std::same_as<typename T::value_type>;
});

A working trick can be:

{ 0   t[0] } -> std::integral;

But I want to stick with typename T::value_type

CodePudding user response:

You probably want something like this:

template <typename T, typename U>
concept decays_to = std::same_as<std::decay_t<T>, U>;

To use as:

template<typename T>
concept IntegralVector =
    std::integral<typename T::value_type>
    && requires (T t) {
        { t.size() } -> std::convertible_to<std::size_t>;
        { t[0] } -> decays_to<typename T::value_type>;
    };

This also catches value_type const& as an option, which I'm not sure was intentionally omitted.

CodePudding user response:

Another alternative is to use C 23 auto(x), which is the decay-copy in the language:

#include<concepts>

template<typename T>
concept IntegralVector = std::integral<typename T::value_type> &&
requires(T t) {
  { t.size() } -> std::convertible_to<std::size_t>;
  { auto(t[0]) } -> std::same_as<typename T::value_type>;
};

Demo.

  • Related