C++ 理解指针和std::向量的std::swap

C++ 理解指针和std::向量的std::swap,c++,swap,C++,Swap,我有以下玩具示例: #include<iostream> #include<vector> int main(){ std::vector<int> a={1, 2, 3}; std::vector<int> b={4, 5, 6}; int* pa = a.data(); int* pb = b.data(); std::swap(pa,pb); std::cout<<"af

我有以下玩具示例:

#include<iostream>
#include<vector>


int main(){


    std::vector<int> a={1, 2, 3};
    std::vector<int> b={4, 5, 6};

    int* pa = a.data();
    int* pb = b.data();

    std::swap(pa,pb);
    std::cout<<"after std::swap(pa,pb)\n";
    std::cout<<"a= "<<a[0]<<" "<<a[1]<<" "<<a[2]<<"\n";
    std::cout<<"b= "<<b[0]<<" "<<b[1]<<" "<<b[2]<<"\n";

    std::cout<<"pa= "<<pa[0]<<" "<<pa[1]<<" "<<pa[2]<<"\n";
    std::cout<<"pb= "<<pb[0]<<" "<<pb[1]<<" "<<pb[2]<<"\n";

    std::swap(a,b);

    std::cout<<"after std::swap(a,b)\n";
    std::cout<<"a= "<<a[0]<<" "<<a[1]<<" "<<a[2]<<"\n";
    std::cout<<"b= "<<b[0]<<" "<<b[1]<<" "<<b[2]<<"\n";

    std::cout<<"pa= "<<pa[0]<<" "<<pa[1]<<" "<<pa[2]<<"\n";
    std::cout<<"pb= "<<pb[0]<<" "<<pb[1]<<" "<<pb[2]<<"\n";
}
#包括
#包括
int main(){
向量a={1,2,3};
向量b={4,5,6};
int*pa=a.data();
int*pb=b.data();
标准:交换(pa,pb);
标准::cout指出:

所有迭代器和引用都保持有效。结束迭代器的过去部分无效

这意味着内存分配保持不变,向量场交换

  std::vector<int> a={1, 2, 3}; // data lays at pa
  std::vector<int> b={4, 5, 6}; // data lays at pb

  int* c = a.data(); // == pa
  int* d = b.data(); // == pb

  std::swap(c,d); // c == pb, d == pa
  std::cout<<"after std::swap(c,d)\n";
  std::cout<<"a= "<<a[0]<<" "<<a[1]<<" "<<a[2]<<"\n";
  std::cout<<"b= "<<b[0]<<" "<<b[1]<<" "<<b[2]<<"\n";

  std::cout<<"c= "<<c[0]<<" "<<c[1]<<" "<<c[2]<<"\n";
  std::cout<<"d= "<<d[0]<<" "<<d[1]<<" "<<d[2]<<"\n";

  std::swap(a,b); // c == pb, d == pa, a == pb, b == pa

  std::cout<<"after std::swap(a,b)\n";
  std::cout<<"a= "<<a[0]<<" "<<a[1]<<" "<<a[2]<<"\n";
  std::cout<<"b= "<<b[0]<<" "<<b[1]<<" "<<b[2]<<"\n";

  std::cout<<"c= "<<c[0]<<" "<<c[1]<<" "<<c[2]<<"\n";
  std::cout<<"d= "<<d[0]<<" "<<d[1]<<" "<<d[2]<<"\n";
std::vector a={1,2,3};//数据位于pa
向量b={4,5,6};//数据位于pb
int*c=a.data();//==pa
int*d=b.data();//==pb
std::swap(c,d);//c==pb,d==pa
标准::cout指出:

所有迭代器和引用都保持有效。结束迭代器的过去部分无效

这意味着内存分配保持不变,向量场交换

  std::vector<int> a={1, 2, 3}; // data lays at pa
  std::vector<int> b={4, 5, 6}; // data lays at pb

  int* c = a.data(); // == pa
  int* d = b.data(); // == pb

  std::swap(c,d); // c == pb, d == pa
  std::cout<<"after std::swap(c,d)\n";
  std::cout<<"a= "<<a[0]<<" "<<a[1]<<" "<<a[2]<<"\n";
  std::cout<<"b= "<<b[0]<<" "<<b[1]<<" "<<b[2]<<"\n";

  std::cout<<"c= "<<c[0]<<" "<<c[1]<<" "<<c[2]<<"\n";
  std::cout<<"d= "<<d[0]<<" "<<d[1]<<" "<<d[2]<<"\n";

  std::swap(a,b); // c == pb, d == pa, a == pb, b == pa

  std::cout<<"after std::swap(a,b)\n";
  std::cout<<"a= "<<a[0]<<" "<<a[1]<<" "<<a[2]<<"\n";
  std::cout<<"b= "<<b[0]<<" "<<b[1]<<" "<<b[2]<<"\n";

  std::cout<<"c= "<<c[0]<<" "<<c[1]<<" "<<c[2]<<"\n";
  std::cout<<"d= "<<d[0]<<" "<<d[1]<<" "<<d[2]<<"\n";
std::vector a={1,2,3};//数据位于pa
向量b={4,5,6};//数据位于pb
int*c=a.data();//==pa
int*d=b.data();//==pb
std::swap(c,d);//c==pb,d==pa

std::cout一个向量倾向于用一个指向数据的指针来实现。因此,假设在内存中有一个名为
foo
的位置,它是
{1,2,3}
的起始位置,而
bar
{4,5,6}
的起始位置

std::vector<int> a={1, 2, 3};
std::vector<int> b={4, 5, 6};
c
是指向
a
的指针当前指向的对象的指针;
foo

d
是指向
b
的指针当前指向的对象的指针;
bar

int* c = a.data();
int* d = b.data();
现在,让我们做一些交换

std::swap(c, d);
c
是一个指针,现在指向
d
所指向的;
bar

d
是一个指针,现在指向
c
所指向的;
foo

所以
c
现在将指向
{4,5,6}
d
现在将指向
{1,2,3}

std::swap(a, b);
a
的指针现在指向
b
的指针所指向的;
bar

b
的指针现在指向
a
的指针所指向的;
foo


交换向量会交换它们所指向的内容;它不会交换内部的实际数据。

向量往往是通过指向数据的指针来实现的。因此,假设内存中有一个名为
foo
的位置,它是
{1,2,3}
的起始位置,而
bar
的起始位置{4,5,6}

std::vector<int> a={1, 2, 3};
std::vector<int> b={4, 5, 6};
c
是指向
a
的指针当前指向的对象的指针;
foo

d
是指向
b
的指针当前指向的对象的指针;
bar

int* c = a.data();
int* d = b.data();
现在,让我们做一些交换

std::swap(c, d);
c
是一个指针,现在指向
d
所指向的;
bar

d
是一个指针,现在指向
c
所指向的;
foo

所以
c
现在将指向
{4,5,6}
d
现在将指向
{1,2,3}

std::swap(a, b);
a
的指针现在指向
b
的指针所指向的;
bar

b
的指针现在指向
a
的指针所指向的;
foo


交换向量会交换它们所指向的内容;它不会交换内部的实际数据。

我认为移动后,您不能(合法地)通过旧的
.data()
指针访问数据it@appleapple是的,您可以,容器仍然处于有效但未定义的状态moving@GuillaumeRacicot如果是未定义状态,为什么要使用旧的
.data()
指针保持有效?我可以为空,也可以是指向新数组的指针,也可以再次指向旧数据。标准规定,从
std
移动的对象中指定的值将具有有效状态,但没有说明它应该采用的实际值。如果希望它们具有定义值,可以给他们分配一个空值
a=std::vector{}
@Yakk抱歉,更改了…我认为移动后您不能(合法地)通过旧的
.data()
指针访问数据it@appleapple是的,您可以,容器仍然处于有效但未定义的状态moving@GuillaumeRacicot如果它是未定义状态,为什么要使用old
.data()
指针保持有效?我可以为空,也可以是指向新数组的指针,也可以再次指向旧数据。标准规定,从
std
移动的对象中指定的值将具有有效状态,但没有说明它应该采用的实际值。如果希望它们具有定义值,可以给他们分配一个空值
a=std::vector{}
@Yakk抱歉,更改了。。。