我正在尝试用 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/