以下代码演示了确保 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

因为您正在尝试将临时绑定(bind)到非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();

但是该标准并不能保证是否满足缩小要求。

如果确实需要,可以使用它,但是请不要从标准容器继承。这不是一件安全的事情:冒着调用错误析构函数的风险。

关于c++ - C++技巧可确保 vector 的重新分配,但是GNU g++的编译问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7995127/

10-11 22:29
查看更多