我有以下内容:
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
}
};
主要:
SpecialContainer<int> x;
x[2] = 3;
这不会编译,因为在类SpecialContainer
中,operator[]
和AbsContainer
中的那个一样。
从概念上讲,Proxy operator[]
应该是一个替代。因此,我尝试通过使Proxy从T继承来实现协变返回类型来解决此问题。但是,由于T可以是原始类型,所以它不起作用,并且从原始类型继承是没有意义的。
由于操作员冲突而导致的错误:
error: conflicting return type specified for ‘specialContainer<T>::Proxy B<T>::operator[](std::ptrdiff_t) [with T = int; std::ptrdiff_t = long unsigned int]
由于尝试继承参数类型T(在这种情况下为int
)而导致的错误:
error: base type ‘int’ fails to be a struct or class type
有什么办法可以解决这个问题?
答案 0 :(得分:0)
即使不为实际的协变类型提供任何编译器支持,您也可以实现与协变类型非常相似的功能。这是这样做的方法。
#include <cstddef>
#include <map>
#include <string>
#include <iostream>
template<typename T>
class AbsContainer {
public:
T operator[](ptrdiff_t i) { return operator_Abs(i); }
virtual T operator_Abs(ptrdiff_t) = 0;
};
template<typename T>
class SpecialContainer : public AbsContainer<T>, std::map<ptrdiff_t, T> {
public:
class Proxy;
Proxy operator[](ptrdiff_t i) { return operator_Spec(i); }
T operator_Abs(ptrdiff_t i) override {
return operator_Spec(i).get();
}
virtual Proxy operator_Spec(ptrdiff_t i) {
return Proxy(i, this);
}
};
template <typename T>
class SpecialContainer<T>::Proxy {
ptrdiff_t _i;
std::map<ptrdiff_t, T>* _p;
public:
Proxy(ptrdiff_t i, std::map<ptrdiff_t, T>* p) : _i(i), _p(p) {};
Proxy& operator=(const T& elm) {
_p->insert(std::pair<ptrdiff_t,T>(_i,elm));
return *this;
}
T get() { return (*_p)[_i]; }
};
int main()
{
SpecialContainer<std::string> spec;
AbsContainer<std::string>& abs = spec;
auto k = spec[42];
k = "Hello World";
std::cout << abs[42] << "\n";
}