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