visualc++的技巧,以确保释放一个矢量,但编译问题与GNU g++
visual C++ trick to ensure deallocation of a vector, but compilation problems with GNU g++
下面的代码演示了一个确保vector完全释放的技巧:
#include <vector>
using namespace std;
template<typename T>
class tvector : public vector<T>
{
public:
typedef vector<T> base;
void swap(tvector<T>& v) {
// do some other stuff, but omitted here.
base::swap(v); }
};
int main()
{
tvector<int> tv1;
// imagine filling tv1 with loads of stuff, use it for something...
// now by swapping with a temporary declaration of an empty tvector that should
// go out of scope at the end of the line, we get all memory used by tv1 returned
// to the heap
tv1.swap(tvector<int>());
}
好吧,这工作在Visual c++ (cl.exe),但使用GNU g++不能编译,有这个错误:
test.cpp: In function ‘int main()’:
test.cpp:18:28: error: no matching function for call to ‘tvector<int>::swap(tvector<int>)’
test.cpp:10:7: note: candidate is: void tvector<T>::swap(tvector<T>&) [with T = int]
这是一个错误在g++,还是我的代码真的是错误的c++代码?
我使用g++解决这个释放技巧的方法是:
int main()
{
tvector<int> tv1;
{
tvector<int> t;
tv1.swap(t);
}
}
对此有什么意见吗?
这些都是众所周知的。释放vector对象内容的标准方法是:
std::vector<int> v;
// Do stuff with v
std::vector<int>().swap(v); // clears v
请注意,反向不起作用:
v.swap(std::vector<int>()); // compile time error
,因为您试图将临时对象绑定到非const引用,这是被禁止的。
Visual Studio允许将此作为非标准扩展,但将警告级别提高到/W3 (IIRC)会触发"使用的非标准扩展"警告。
在c++ 11中(从技术上讲在c++ 03中也是如此!),您可以简单地执行
v = std::vector<int>();
或者,如果你喜欢冗长的内容(仅限c++ 11),还有
v.clear(); // or v.resize(0);
v.shrink_to_fit();
但是标准并没有保证收缩请求是否被满足。
如果你真的需要的话,你可以使用这个,但是请注意,不要继承标准容器。这样做并不安全:你有可能调用错误的析构函数。
使用temporary调用swap
方法,它不存储在任何地方。它不能作为引用,因为从编译器的角度来看,它没有存储在任何地方。tvector<int>
vs . tvector<int>&
您正在寻找这个习语来释放vector的保留内存:
tvector<int>().swap(tv1);
不允许将临时变量传递给swap
,因为swap
接受一个非const引用(换句话说,它需要一个可以修改的非临时变量)。(我很惊讶Visual c++居然接受这些代码。)
如果你使用Clang而不是gcc,它会为你解释:
<>之前测试。Cc:35:14:错误:对类型'tvector'的非const左值引用不能绑定到'tvector'类型的临时对象tv1.swap (tvector ());^~~~~~~~~~~~~~测试。Cc:22:27:注意:在这里传递参数给参数'v'无效交换(向量& v) {之前这个习惯用法的正确版本是有效的,因为它创建了一个为整个语句保持创建的变量,然后传递了一个非临时参数。