gpt4 book ai didi

C++ 为什么箭头 (->) 运算符的自动重新应用不适用于指针到指针类型?

转载 作者:行者123 更新时间:2023-11-30 03:24:26 25 4
gpt4 key购买 nike

This question讨论箭头运算符 -> 如何自动重新应用于重载的 operator->() 的返回值,直到返回的值是原始指针,此时原始指针被取消引用,就像使用 -> 一样。然而,当他们希望取消对基值的引用时,情况就不一样了——他们必须使用 (*ptr_to_ptr)->foo() 来代替。在我看来,作为 ptr_to_ptr->foo() 的用法是明确的,甚至比将 -> 自动重新应用到返回值直到原始指针被退回。那么,这个决定背后的原因是什么?

最小工作示例:

#include <iostream>

struct Dog {
void bark() { std::cout << "woof!" << std::endl; }
};

struct DogWalker {
Dog* dog;
Dog* operator->() {
return dog;
}
};

struct DogOwner {
DogWalker walker = { new Dog() };
DogWalker operator->() {
return walker;
}
};

void main()
{
DogOwner owner;
owner->bark(); // works, prints "woof"

Dog** ptr_to_ptr = new Dog*;
*ptr_to_ptr = new Dog;
(**ptr_to_ptr).bark(); // works
(*ptr_to_ptr)->bark(); // works
//ptr_to_ptr->bark(); // ERROR
//C2227: left of '->bark' must point to class/struct/union/generic type
}

最佳答案

该语言采用了 C 语言的大部分语义。应用于指针类型的 -> 运算符仅在指针指向非数组复合类型时才有效。由于 C 没有类,C++ 为重载的 -> 定义了自己的语义,这对智能指针用例有意义。

您可以使用辅助类实现您想要的行为。

template <typename T>
struct Unwrap {
T *p_;
Unwrap (T *p = 0) : p_(p) {}
T * operator -> () const { return p_; }
};

template <typename T>
struct Unwrap<T *> {
T **p_;
Unwrap (T **p = 0) : p_(p) {}
Unwrap<T> operator -> () const { return *p_; }
};

template <typename T>
Unwrap<T> make_unwrap (T *p) { return p; }

然后你可以像这样使用它:

struct foo {
void bar () { std::cout << "Hello\n"; }
};

int main () {
foo p;
auto pp = &p;
auto ppp = &pp;
auto pppp = make_unwrap(&ppp);

pppp->bar();
}

Try it online!

关于C++ 为什么箭头 (->) 运算符的自动重新应用不适用于指针到指针类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49701907/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com