【问题标题】:C++ Swapping pointers - can't reproduce auto type by defining type explicityC++ 交换指针 - 不能通过明确定义类型来重现自动类型
【发布时间】:2021-11-10 15:22:51
【问题描述】:

在 C++ Primer 中做练习 6.22,一个交换两个指针的函数

void swap(int*& a, int*& b) {
    auto temp = a;
    a = b;
    b = temp;
}

int main()
{
    int a = 15;
    int b = 4;
    int* p1 = &a;
    int* p2 = &b;
    cout << "p1 address: " << p1 << "; p1 value: " << *p1 << "\np2 address: " << p2 << "; p2 value: " << *p2 << endl;
    swap(p1, p2);
    cout << "p1 address: " << p1 << "; p1 value: " << *p1 << "\np2 address: " << p2 << "; p2 value: " << *p2 << endl;
}

不确定它是否正确,但它按预期工作,值和地址已交换。我在 MS Visual Studio 中将鼠标悬停在 a 内的 swap 函数上:

它告诉我类型是int*&amp;,但是将temp 的定义更改为int*&amp; temp = a 会破坏程序:

p1 address: 004FFE00; p1 value: 15
p2 address: 004FFDF4; p2 value: 4
p1 address: 004FFDF4; p1 value: 4
p2 address: 004FFDF4; p2 value: 4

这里的正确类型是什么? MS Visual Studio 类型工具提示背后的逻辑是什么?

【问题讨论】:

  • 工具提示通知您a 的类型,而不是temp。这里auto tempint* temp 而不是int* &amp; temptemp是否使用类型推导对a的类型没有影响。
  • temp = a 需要复制指针,而不是为其创建新的别名(引用)。
  • [ProTip] auto 和模板参数永远不会推断为引用类型。如果你想要一个引用类型,你必须通过在类型后面添加&amp;来指定它。
  • 这可能是 C++ auto vs auto& 的副本。
  • @FrançoisAndrieux 傻我!但当然可以!让自己在两周后重新开始学习 C++ 很艰难,所以我变得非常生疏。感谢大家的帮助!

标签: c++ visual-c++


【解决方案1】:

如 cmets 中所述,temp 的类型为 int*,而不是 int*&amp;。如果您希望它是对指针的引用,您可以显式声明类型或使用auto&amp;。但是,无论如何,您真正想要的是int*。想一想,如果你交换两个 ints,你会怎么写:

void swap(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}

在这里,您希望 temp 只是一个 int,因为您只希望它存储 a 的值,以便您可以将其复制到 b。没有必要作为参考。

关于您的另一个问题,当temp 是参考时会发生什么?

  • a = 15
  • b = 4
  • 致电swap()
  • temp 引用 a
  • a 引用 b(所以 temp 引用 b
  • b 引用 temp(所以 b 引用 b
  • ab 现在都引用值 4

要查看实际情况,请在调试模式下遍历函数并检查每一步的指针地址和值。

【讨论】:

  • 感谢您的详细解释,真正消除了我对此的困惑。而且调试建议绝对正确,我早该想到的。
【解决方案2】:

swap函数可以这样改。

template<typename T>
void swap(T& a, T& b) {
    auto temp = a;
    a = b;
    b = temp;
}

首先您的问题是int*&amp; 的类型。在我的功能中,您的问题与T&amp; 的类型相同。 T&amp; 的意思是参考 T。所以int*&amp; 的意思是参考int*

这就是为什么在使用 int*&amp; 时不会更改 P2。 但如果你使用autotemp 类型是int*。这就是它运作良好的原因。

【讨论】:

  • 如果你想泛化函数,那很好。您还应该移动所有东西。
  • @sweenish 你的评论是好意见。但我想专注于类型问题。谢谢你的好意。
  • 如果您超出了 OP 的问题,我会说一路走下去,或者至少声明它仍然不完整。
  • 我还没有学过模板,但是我对这个意思的猜测应该是对的。 @sweenish 的意思是你应该使用T temp = a; 而不是auto temp = a;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多