visualc++的技巧,以确保释放一个矢量,但编译问题与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) {之前

这个习惯用法的正确版本是有效的,因为它创建了一个为整个语句保持创建的变量,然后传递了一个非临时参数。

相关内容

最新更新