对列表类中的泛型方法禁用编译器警告 2100,该泛型方法可能包含指针,也可能不包含指针

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

本文关键字:泛型方法 指针 包含 也可能 2100 警告 列表 编译器      更新时间:2023-10-16

我正在尝试在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,并且该块中的代码无论如何都不会执行,所以这应该不是问题。禁用警告似乎无济于事。

如果我这样做:

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 如果条件不为 true,它将从编译中删除代码。

如果您无权访问支持该功能的编译器,则必须使用 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;
}
}