Boost :: ptr_vector更改元素顺序

时间:2014-10-10 15:18:05

标签: c++ boost

请有人告诉我如何在没有相同ptr_vector的情况下切换两个元素的位置 新的动态内存分配。也就是说,我想使用std::vector执行与下面相同的操作,但使用boost::ptr_vector

此外,这必须使用索引来完成,而不是ptr_vector::iterator

void switch( vector<int>& V , size_t i , size_t j){
    int a  = V[ j ];
    V[ j ] = V[ i ];
    V[ i ] = a;
}

谢谢大家。

3 个答案:

答案 0 :(得分:2)

(未经测试),我想它必须是这样的:

void switch( ptr_vector<int>& V , size_t i , size_t j){
  auto p = V.replace(i, nullptr); // should get you the value there..
  auto k = V.replace(j, p);       // should get you the value there..
  auto res = V.replace(i, k);
  assert(res == nullptr); // this should be the case...
}

答案 1 :(得分:2)

boost::ptr_vector<T> v;
size_t i = whatever, j = whatever;

// Put this in a separate function
// Do NOT use it as a subexpression or you may (?) forfeit exception safety
v.replace(j, v.replace(i, &v[j]).release()).release();

答案 2 :(得分:0)

您可以只交换元素值:

using std::swap;
swap(v[1], v[2]);

这将完全符合您对std :: vector案例的预期。这是一个使用sentinel类型来跟踪分配的演示: Live On Coliru (它不会为交换做任何新的分配)

打印:

static void* X::operator new(size_t)(4)
X::X(int)(1)
static void* X::operator new(size_t)(4)
X::X(int)(2)
static void* X::operator new(size_t)(4)
X::X(int)(3)
static void* X::operator new(size_t)(4)
X::X(int)(4)
X[1] X[2] X[3] X[4] 
===============================
swapping v[1] and v[2]:
X::X(X&&)(X[2])
X& X::operator=(X&&)(X[3])
X& X::operator=(X&&)(X[2])
X::~X()

===============================
X[1] X[3] X[2] X[4] X::~X()
static void X::operator delete(void*)
X::~X()
static void X::operator delete(void*)
X::~X()
static void X::operator delete(void*)
X::~X()
static void X::operator delete(void*)

完整计划

#include <boost/ptr_container/ptr_vector.hpp>

struct X {
    X(int i) : _i(i)         { std::cout << __PRETTY_FUNCTION__ << "(" << i << ")" << "\n"; }
    X(X && x) : _i(x._i)     { std::cout << __PRETTY_FUNCTION__ << "(" << x << ")" << "\n"; }
    X(X const& x) : _i(x._i) { std::cout << __PRETTY_FUNCTION__ << "(" << x << ")" << "\n"; }
    ~X()                     { std::cout << __PRETTY_FUNCTION__ << "\n"; }

    void* operator new(size_t n) {
         std::cout << __PRETTY_FUNCTION__ << "(" << n << ")" << "\n";
         return ::operator new(n);
    }

    void operator delete(void* px) {
         std::cout << __PRETTY_FUNCTION__ << "\n";
         return ::operator delete(static_cast<X*>(px));
    }

    X& operator=(X const& x) { 
        _i = x._i;
        std::cout << __PRETTY_FUNCTION__ << "(" << x << ")" << "\n"; 
        return *this;
    }

    X& operator=(X && x) { 
        _i = x._i;
        std::cout << __PRETTY_FUNCTION__ << "(" << x << ")" << "\n"; 
        return *this;
    }

    friend std::ostream& operator<<(std::ostream& os, X const& x) {
        return os << "X[" << x._i << "]";
    }
    private: int _i;
};

int main()
{
    boost::ptr_vector<X> v;
    v.push_back(new X(1));
    v.push_back(new X(2));
    v.push_back(new X(3));
    v.push_back(new X(4));

    for (auto& p : v)
        std::cout << p << " ";

    std::cout << "\n===============================\nswapping v[1] and v[2]:\n";

    using std::swap;
    swap(v[1], v[2]);

    std::cout << "\n===============================\n";

    for (auto& p : v)
        std::cout << p << " ";
}