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>;
};