简体   繁体   English

下标运算符重载用于部分模板专业化

[英]Subscript operator overload for partial template specialisation

I'm trying to learn about templates and template specialisation. 我正在尝试了解模板和模板专业化。 I'm writing a template class for arrays, using template specialisation to avoid code bloat. 我正在为数组编写模板类,使用模板专业化来避免代码膨胀。 Thus I have a fully specialised template MyArray and then I inherit from this one like class MyArray<T*> : private MyArray<void*> . 因此,我有一个完全专用的模板MyArray,然后从该模板继承,例如class MyArray<T*> : private MyArray<void*> I'm having trouble overloading the subscript operators (one for non-const refs, one for const refs). 我在重载下标运算符时遇到麻烦(一个用于非const引用,一个用于const引用)。 Here's a piece of code (far from complete, but contains my problem). 这是一段代码(远未完成,但包含了我的问题)。

#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;
}

The compiler (clang) is complaining (error) about line 26 编译器(clang)抱怨(错误)关于第26行

non-const lvalue reference to type 'const void *' cannot bind to a value of unrelated type 'void *' 对类型'const void *'的非const左值引用不能绑定到不相关的类型'void *'的值

I suppose I don't want the compiler to interpret this as a non-const reference - what I want is for it to be const. 我想我不希望编译器将此解释为非const引用-我想要的是使其成为const。 How can I properly overload this operator in this context? 在这种情况下,如何正确重载该运算符? The corresponding piece of code works fine for a template class without specialisation, like MyArray<T> . 对应的代码段对于没有专门化的模板类(如MyArray<T>

The compiler further complains (warnings) about the reinterpret_cast s which apparently contain undefined behaviour 编译器进一步抱怨(警告)关于reinterpret_cast ,其中显然包含未定义的行为

reinterpret_cast from 'void *' to 'int *&' has undefined behavior 从'void *'到'int *&'的reinterpret_cast具有未定义的行为

(line 47). (第47行)。 The reinterpret_casts are essentially copy-pasted from my instructions, so I would think they are to be used like this. reinterpret_casts本质上是从我的说明中复制粘贴的,因此我认为它们将像这样使用。 I don't know why the reference to void* isn't picked up. 我不知道为什么未引用void* What am I doing wrong here? 我在这里做错了什么?

Your template is a container for void* , not const void* : 您的模板是void*的容器,而不是const void*

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

Same for T* : T*相同:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM