I frequently have to implement "container-like" classes in C++ and I find that I often forget to implement one part of the interface and have problems later. To fix this I want to create an abstract Container
class that I can make my container classes inherit from that will fail to compile if any of the required interface functions are not implemented.
The issue is container classes typically define a size_type
and I want the size()
function to return the corresponding size_type
of whatever the underlying container is.
Here is a simplified example of what I am talking about:
#include <vector>
// Abstract class
template <typename T>
class Container
{
public:
virtual ~Container() = 0;
//********************************************************************************
// How do I tell it to return whatever "size_type" is for the child class?
//********************************************************************************
virtual typename ChildClass::size_type size() const = 0;
};
template <typename T>
Container<T>::~Container() = default;
// Concrete
template <typename T>
class MyVector final : public Container<T>
{
public:
// size_type of the child class defined here
using size_type = typename std::vector<T>::size_type;
MyVector()
: m_data()
{}
size_type size() const override
{
return m_data.size();
}
private:
std::vector<T> m_data;
};
Is there any way to reference the size_type
of whatever the child class is in the abstract function definition of size()
?
EDIT
After applying the CRTP (recommended below) I feel like I am much closer, but it is still failing to compile the second I try to instantiate an object of MyVector<double>
:
// Abstract class
template <typename T>
class Container {
public:
virtual ~Container() = default;
// Still can't seem to resolve the type here
virtual typename T::size_type size() const = 0;
};
// Concrete
template <typename T>
class MyVector final : private Container<MyVector<T>> {
public:
using size_type = typename std::vector<T>::size_type;
using value_type = T;
size_type size() const
{
return m_data.size()
}
private:
std::vector<T> m_data;
};
int main()
{
// Fails to compile
MyVector<double> v;
}
I get the compiler error:
error C2039: 'size_type': is not a member of 'MyVector'