С++ 20 реализовать интерфейс для вектора

Я хотел бы создать класс, в котором можно использовать любой вектор.

Возможными типами могут быть std::vector, boost::vector, etl::vector.

Все используемые векторные типы должны реализовывать функции-члены std::vector. Я хотел бы создать концепцию, которая подтверждает, что используемый векторный тип реализует все функции-члены std::vector

До сих пор я придумал

#include <concepts>
#include <vector>

template < typename T , typename Element_T>
concept IVector_T = requires(T vec, Element_T elem)
{
  {vec.push_back(elem) } -> std::same_as<void>;  ///< Add an element to the vector
  {vec.back()} ->std::convertible_to<Element_T>;
};

template<typename Element_T, IVector_T Vector_T>
class TestVector
{
public:
  void push_back(const Element_T& elem)
  {
    myVec.push_back(elem);
  }
  Element_T& back()
  {
    //return ref to last element
    return myVec.back();
  }
private:
  Vector_T<Element_T> myVec;
};

Однако я получаю ошибку компилятора

<source>(27): error C2059: syntax error: '<'
<source>(28): note: see reference to class template instantiation 'TestVector<Element_T,Vector_T>' being compiled
<source>(27): error C2238: unexpected token(s) preceding ';'
<source>(19): error C3861: 'myVec': identifier not found
<source>(19): error C2065: 'myVec': undeclared identifier

Я использую последнюю версию MSVC17 на Win 10, однако она также должна работать на Linux и Mac.

У меня есть ссылка на Godbolt, чтобы вы могли легко воспроизвести эту проблему. https://godbolt.org/z/54zac583j

Спасибо за вашу помощь, ребята :)

Редактировать: Как отмечено в комментариях, pop_into() не является стандартным. => заменил его на back().

Чтобы уточнить: для некоторых векторов, таких как boost::vector и std::vector, требуется 1 аргумент шаблона (например, std::vector) Другим типам векторов, таким как etl::vector, может потребоваться больше аргументов шаблона. etl::vector, например, является предварительно выделенным вектором, поэтому нам нужен максимальный размер вектора (т.е. etl::vector<int, 100>)

Отвечает ли это на ваш вопрос? Можно ли использовать понятия с параметрами шаблона шаблона?

Nelfeal 21.11.2022 13:47

Является ли Vector_T параметром шаблона шаблона?

康桓瑋 21.11.2022 13:48

И что такое pop_into? Вы имели в виду pop_back?

Nelfeal 21.11.2022 13:48
IVector_T имеет дополнительный параметр шаблона Element_T. Это, вероятно, не то, что вы хотите. Требуйте, чтобы T::value_type был типом, и используйте его вместо этого.
n. m. 21.11.2022 13:51

извини моя вина. Замените pop_into(). и да, Vector_T — это параметр шаблона шаблона. Типы Vector_T могут быть std::vector<T> и etl::vector<T, MAX_VEC_SIZE>.

JHeni 21.11.2022 15:15

@н.м. как я могу использовать T::value_type в этом контексте?

JHeni 21.11.2022 15:15

Смотрите это демо. Обратите внимание, что это работает совсем не так, как все предлагаемые решения. В этой демонстрации вы всегда работаете с std::vector<int>, а не с двумя отдельными сущностями std::vector и int, или std::vector<int> и int, или чем-то еще. В демонстрации вектор даже не обязательно должен быть экземпляром шаблона. Или это может быть экземпляр шаблона с большим количеством параметров. Это тип, а не шаблон.

n. m. 21.11.2022 15:50
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
1
7
139
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я бы использовал более явный синтаксис. Это компилирует:

template<typename Element_T,
         template <typename Elem> typename Vector_T>
requires IVector_T<Vector_T<Element_T>, Element_T>
class TestVector
{
...

(Однако я не пытался скомпилировать один из его экземпляров.)

Ваш Vector_T — это шаблон, поэтому я думаю, что необходимо явно превратить TestVector в «шаблон шаблона».

Кроме того, IVector_T требует двух аргументов, поэтому использование template <IVector_T Vector_T> некорректно: каким будет другой аргумент?

Не уверен, как вы планируете создавать экземпляр этого типа, но, учитывая переменную-член, я подозреваю, что вы неправильно указали аргументы шаблона:

template<typename Element_T, template <typename> typename Vector_T>
requires(IVector_T<Vector_T<Element_T>, Element_T>)
class TestVector { // ...
Ответ принят как подходящий

Вы должны создать экземпляр шаблона Vector_T следующим образом.

template<typename Element_T, IVector_T<Element_T> Vector_T>
class TestVector
{
...
private:
    Vector_T myVec;
};

Другие вопросы по теме