用于部分模板特化的下标操作符重载

Subscript operator overload for partial template specialisation

本文关键字:下标 操作符 重载 用于部      更新时间:2023-10-16

我想了解模板和模板专门化。我正在为数组编写一个模板类,使用模板专门化来避免代码膨胀。因此,我有一个完全专门的模板MyArray,然后我继承这个像class MyArray<T*> : private MyArray<void*>。我在重载下标操作符时遇到了麻烦(一个用于非const refs,一个用于const refs)。下面是一段代码(远未完成,但包含了我的问题)。

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
/*** template class MyArray   **/
template <class T>
class MyArray {};
/*** Full template specialization for MyArray holding pointers ***/
template <> 
class MyArray<void*> {
    public:
        explicit MyArray(unsigned s = 100) : sz(s) {
            data = new void*[s]; 
        }
        virtual ~MyArray() { delete[] data; }
        /** subscript operator overload for non-const refs **/
        void*& operator[](unsigned i) {
            return data[i];
        }
        /** subscript operator overload for const refs **/
        const void*& operator[](unsigned i) const {
            return data[i];    // line 26
        }
        unsigned size() const { return sz; }
    private: 
        void** data;
        unsigned sz;
};
/** Partial specialization: create the template class by inheriting from the one above **/
template <class T>
class MyArray<T*> : private MyArray<void*> {
    public:
        explicit MyArray(unsigned s = 100) : MyArray<void*>::MyArray(s) {
            data = new T*[s];  
        }
        virtual ~MyArray() { delete[] data; }
        /** subscript operator overload for non-const refs **/
        T*& operator[](unsigned i) {
            return reinterpret_cast<T*&>(      // line 47
                MyArray<void*>::operator[](i)
            );
        }
        /** subscript operator overload for const refs **/
        const T*& operator[](unsigned i) const {
            return reinterpret_cast<const T*&>(
                MyArray<void*>::operator[](i)
            );
        }

        unsigned size() const { return MyArray<void*>::size(); }
    private:
        T** data;
};
/** input function for filling MyArray's  **/
template <class T>
void InputMyArray(MyArray<T*>& my_array) {
    unsigned size = 0;
    T tmp;
    while (cin >> tmp) {
        T* i = new T;
        *i = tmp;
        my_array[size++] = i;
    }
}
/** output function for printing elements of MyArray's **/
template <class T>
void OutputArray(const MyArray<T*>& my_array) {
    for (unsigned i = 0; i < my_array.size(); i++) {
        cout << *my_array[i] << " ";
    }
    cout << endl;
}
int main() {
    /** Initialize array, fill it, print contents **/
    MyArray<int*> p;
    InputMyArray(p);
    cout << "MyArray of pointer to ints holds int values: " << endl;
    OutputArray(p);
    return 0;
}

编译器(clang)抱怨(错误)关于第26行

对类型'const void *'的非const左值引用不能绑定到不相关类型'void *'的值

我想我不希望编译器将其解释为非const引用-我想要的是它是const。如何在这种上下文中正确地重载此操作符?相应的代码段对于没有特化的模板类工作得很好,比如MyArray<T>

编译器进一步抱怨(警告)reinterpret_cast s显然包含未定义的行为

reinterpret_cast from 'void *' to 'int *&'有未定义行为

(47行)。reinterpret_casts基本上是从我的指令复制粘贴的,所以我认为它们是这样使用的。我不知道为什么没有提到void*。我哪里做错了?

您的模板是void*的容器,而不是const void*:

    /** subscript operator overload for const refs **/
    void* const& operator[](unsigned i) const {
        return data[i];    // line 26
    }

T*:

    /** subscript operator overload for const refs **/
    T* const& operator[](unsigned i) const {
        return reinterpret_cast<T*const&>(
            MyArray<void*>::operator[](i)
        );
    }