[英]C++ trick to ensure deallocation of a vector, but compilation problems with GNU g++
以下代碼演示了一種確保向量完全釋放的技巧:
#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);
}
}
有什么意見嗎?
這眾所周知。 取消分配向量內容的標准教科書技巧是:
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();
但是標准並不保證是否要滿足收縮要求。
如果你真的需要,你可以使用它,但請不要繼承標准容器 。 這不是一件安全的事情:你冒着調用錯誤析構函數的風險。
您可以使用臨時調用swap
方法,該方法不會存儲在任何位置。 它不能作為參考,因為從編譯器的角度來看它不存儲在任何地方。 tvector<int>
與tvector<int>&
。
你正在尋找這個成語來釋放向量的保留內存:
tvector<int>().swap(tv1);
不允許將臨時變量傳遞給swap
,因為swap
采用非const引用(換句話說,它需要一個可以修改的非臨時變量)。 (我很驚訝Visual C ++接受此代碼。)
如果您使用Clang而不是gcc,它會嘗試為您解釋:
test.cc:35:14: error: non-const lvalue reference to type 'tvector' cannot bind to a temporary of type 'tvector' tv1.swap(tvector()); ^~~~~~~~~~~~~~ test.cc:22:27: note: passing argument to parameter 'v' here void swap(tvector& v) {
正確版本的成語有效,因為它創建了一個為整個語句創建的變量,然后傳遞一個非臨時參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.