Search code examples
c++templatesc++20c++-conceptstypename

Restricting a range or similar concept to only accept a given type


I would like to declare a function akin to the following:

string concat(const range<string> auto& strings);

I have achieved the same via the following:

template <template <typename> typename T> requires range<T<string>>
string concat(const T<string>& strings);

But this is too hefty and repetitious for me to consider utilizing.

Is there a cleaner way?

I assume there isn't, since a type concept requires the first template parameter to be a regular typename, which makes giving it a template argument list impossible.

If it is indeed impossible, are there any plans to remedy this apparent flaw? If not, are there any reasons for why this might prove troublesome to specify/implement?


Solution

  • Maybe something like this:

    template <class R, class T>
    concept range_of = std::ranges::range<R> &&
                       std::same_as<std::ranges::range_value_t<R>, T>;
                
    static_assert(range_of<std::vector<int>, int>);
    
    static_assert(range_of<decltype(std::declval<std::vector<int>&>() |
                                    std::views::all),
                           int>);