Использование concept'ов с несколькими type-параметрами

Не могу понять, как и можно ли вообще использовать концепты типа:

template <typename Type1, typename Type2>
concept StdByteContainer =
    (std::same_as<Type1,std::remove_cvref_t<std::basic_string<Type2>>>
        || std::same_as<Type1,std::remove_cvref_t<std::vector<Type2>>>
        || std::same_as<Type1,std::remove_cvref_t<std::list<Type2>>>
        || std::same_as<Type1,std::remove_cvref_t<std::deque<Type2>>>
        || std::same_as<Type1,std::remove_cvref_t<std::set<Type2>>>)
    && (std::same_as<Type2,std::byte>
        || (std::is_integral_v<Type2> && sizeof(Type2)==1));

Пытался писать так:

template <StdByteContainer Type1<Type2>>
void function(const Type1<Type2>& container);

Так:

template <StdByteContainer Type1, StdByteContainer Type2>
void function(const Type1<Type2>& container);

Так:

template <StdByteContainer Type1, Type2>
void function(const Type1<Type2>& container);

Так:

template <StdByteContainer Type1 Type2>
void function(const Type1<Type2>& container);

Никак не выходит, статический анализатор пишет:

error: 'StdByteContainer' requires more than 1 template argument

Так вообще можно писать, или такие концепты в принципе недопустимы? Хотя объявление концепта парсер пропустил, посчитав валидным... Если что, использую GCC-10.


Ответы (1 шт):

Автор решения: user7860670

Видимо идея была, чтобы один параметр был типом контейнера, а другой - типом объектов, хранящихся в этом контейнере. Однако мне это представляется избыточным. Сделал такой пример с одним параметром шаблона и проверкой через зависимые типы.

#include <concepts>
#include <vector>
#include <string>
#include <span>
#include <type_traits>

template <typename x_Container>
concept StdByteContainer = 
    (
        ::std::same_as
        <
            ::std::basic_string<typename x_Container::value_type, typename x_Container::allocator_type>
        ,   ::std::remove_cvref_t<x_Container>
        >
        or
        ::std::same_as
        <
            ::std::vector<typename x_Container::value_type, typename x_Container::allocator_type>
        ,   ::std::remove_cvref_t<x_Container>
        >
        // ...
    )
    and
    ::std::is_integral_v<typename x_Container::value_type>
    and
    (sizeof(typename x_Container::value_type) == 1);

//requires
//{
//    typename x_Container::velue_type;
//};

template <StdByteContainer x_Container>
void checksum(std::span<x_Container> span) {}

int main()
{
    ::std::vector<::std::vector<char>> items{{},{}};
    checksum(::std::span<::std::vector<char>>{items.begin(), items.end()});
}

https://godbolt.org/z/h5E1je

→ Ссылка