I have the following:
template<typename T>
class AbsContainer {
public:
virtual T operator[](ptrdiff_t) = 0;
};
template<typename T>
class SpecialContainer : public AbsContainer<T>, Box<pair<ptrdiff,T>> {
class Proxy;
public:
Proxy operator[](ptrdiff_t i) {
return Proxy(i, this);
};
};
template <typename T>
class SpecialContainer<T>::Proxy {
ptrdiff_t _i;
Box* _p;
public:
Proxy(ptrdiff_t i, Box* p) : _i(i), _p(p);
Proxy& operator=(const T& elm) {
_p->::insert(pair<ptrdiff,T>(_i,elm)); //defined in Box
}
};
main:
SpecialContainer<int> x;
x[2] = 3;
This doesn't compile, because in class SpecialContainer, the operator[] with the one in AbsContainer.
Ideally in concept, Proxy operator[] should be an override. So I tried resolving this by achieving covariant return type by making Proxy inherit from T. However it doesn't work since T can be a primitive type, and inheriting from a primitive type has no sense.
Error because of operator conflict :
error: conflicting return type specified for ‘specialContainer<T>::Proxy B<T>::operator[](std::ptrdiff_t) [with T = int; std::ptrdiff_t = long unsigned int]
Error because trying to inherit from parametric type T (int in this case):
error: base type ‘int’ fails to be a struct or class type
Is there any way in which can this be resolved ?
You can implement something very similar to covariant types even without any compiler support for actual covariant types. Here's how to do it.