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

标签 c++ generics compiler-errors dereference

我正在尝试用 C++ 创建一个 ArrayList 类作为一种学习体验。类似于 Java ArrayList 类它是一个动态数组,内部数组称为'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:“<<”:类非法

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

如果我这样做:

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并且有两个函数重载。一种用于如果 T 是指针类型,另一种用于当 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;
    }
}

关于c++ - 为可能包含或不包含指针的列表类中的泛型方法禁用编译器警告 2100,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45239921/

相关文章:

swift - 是否可以在 Swift 中创建一个仅限于该类型为可选类型的泛型类型的扩展?

c# - 关于泛型和继承(原谅我不好的标题)

c# - 如何在github仓库中找到文件路径?

C++ 指向类方法的指针

c++尝试反向打印数组时出现段错误

c++ - 未定义的“函数引用”

c# - 使用泛型的字典

c++ - C++ 中的 Matlab 类型数组

objective-c - 协议(protocol)定义中的编译器错误 "expected a type"

sql - Microsoft SQL服务器