为可能包含或不包含指针的列表 class 中的泛型方法禁用编译器警告 2100

Disable compiler warning 2100 for generic method in a list class that may contain pointers or not

我正在尝试用 C++ 制作 ArrayList class 作为学习经验。类似于Java ArrayList class它是一个动态数组,内部数组叫做'content'。与 Java 不同,我希望我的 ArrayList 能够接受指针和非指针。但是我遇到了一个问题,我正在使用 std::is_pointer::value 来检查泛型类型是否是多个函数中的指针。如果它是一个指针,则该函数将需要以不同于它不是指针的方式执行。下面的示例显示了我的 printAll() 函数,该函数旨在将数组中的每个元素打印在不同的行上。如果泛型类型是指针,则该方法需要在打印数组之前取消引用数组中的每个元素。

   int main() {
        ArrayList<int> a = ArrayList<int>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.printAll();
        cin.ignore();
    }

    #pragma warning(push)
    #pragma warning(disable : 2100)
    template<class T>
    void ArrayList<T>::printAll() {
        if (std::is_pointer<T>::value) {
            for (int i = 0; i < this->occupiedSize; i++) {
                cout << "[" << i << "] " << *this->content[i];
                cout << endl;
            }
        } else {
            for (int i = 0; i < this->occupiedSize; i++) {
                cout << "[" << i << "] " << this->content[i];
                cout << endl;
            }
        }
    }
    #pragma warning(pop)

线上: cout << "[" << i << "] " << *this->content[i]; 我收到警告: C2100:非法间接和 C2088:“<<”:对于 class

是非法的

我假设这是因为列表不是指针类型,因此不能用 * 取消引用。但是在非指针列表中,std::is_pointer::value 应该 return false 并且该块中的代码永远不会执行,所以这应该不是问题。禁用警告似乎没有帮助。

如果我这样做:

int main() {
    ArrayList<int*> a = ArrayList<int*>();
    a.add(new int(1));
    a.add(new int(2));
    a.add(new int(3));
    a.printAll();
    cin.ignore();
}

它工作得很好。有什么想法可以解决这个问题,或者我可以如何更好地实现这个功能?

我正在使用 windows 10,Microsoft Visual Studio(我相信是最新版本)。

这里的问题是即使你永远不会进入

if (std::is_pointer<T>::value) {
    for (int i = 0; i < this->occupiedSize; i++) {
        cout << "[" << i << "] " << *this->content[i];
        cout << endl;
    }
}

如果T 是非指针类型,编译器仍会编译该代码块。由于它具有非法语法,您会收到编译器警告。

在即将发布的 C++17 中,您可以使用 constexpr if 如果条件不成立,它将从编译中删除代码。

如果您无法访问支持该功能的编译器,那么您将不得不使用 SFINAE 并对该函数进行两次重载。一种用于 if T 是指针类型,另一种用于 when T 不是指针类型。那看起来像

template<class T, std::enable_if_t<typename std::is_pointer<T>::value>* = nullptr>
void ArrayList<T>::printAll() {
    for (int i = 0; i < this->occupiedSize; i++) {
        cout << "[" << i << "] " << *this->content[i];
        cout << endl;
    }
}

template<class T, std::enable_if_t<typename !std::is_pointer<T>::value>* = nullptr>
void ArrayList<T>::printAll() {
    for (int i = 0; i < this->occupiedSize; i++) {
        cout << "[" << i << "] " << this->content[i];
        cout << endl;
    }
}