Home > Net >  c 20 implement an interface for a vector
c 20 implement an interface for a vector

Time:11-21

I'd like to create a class with can use any Vector.

Possible types could be std::vector, boost::vector, etl::vector.

All used vector types must implement std::vector member functions. I'd like to create a concept which validates that the used vector type implements all std::vector member functions

So far I have come up with

#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.pop_into()} ->std::convertible_to<Element_T>; ///< Removes the last element from the vector and returns it
};

template<typename Element_T, IVector_T Vector_T>
class TestVector
{
public:
  void push_back(const Element_T& elem)
  {
    myVec.push_back(elem);
  }
  Element_T pop_into()
  {
    //remove last Element from Vector and return it
    return Element_T();
  }
private:
  Vector_T<Element_T> myVec;
};

However I'm getting a compiler error

<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

I'm using latest MSVC17 on Win 10, however this should also run an Linux and Mac

I have a godbolt link for you to easily reproduce this issue https://godbolt.org/z/54zac583j

Thx for your help guys :)

CodePudding user response:

Not sure how you plan to instantiate this type, but given the member variable, I suspect you didn't properly specify the template arguments:

template<typename Element_T, template <typename> typename Vector_T>
requires(IVector_T<Vector_T<Element_T>, Element_T>)
class TestVector { // ...

CodePudding user response:

I would use a more explicit syntax. This compiles:

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

(I have not tried to compile one of its instantiations, though.)

Your Vector_T is a template, so I think it's required to explicitly make TestVector into a "template template".

Further, IVector_T requires two arguments, so using template <IVector_T Vector_T> is incorrect: what would the other argument be?

CodePudding user response:

You should do template instantiation of Vector_T like this.

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