具有原始类型的协变返回类型

时间:2018-12-12 20:15:52

标签: c++ oop operator-overloading overloading covariant-return-types

我有以下内容:

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

有什么办法可以解决这个问题?

1 个答案:

答案 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";
}