【问题标题】:C++ override member access operator for template class and return by referenceC++ 覆盖模板类的成员访问运算符并通过引用返回
【发布时间】:2021-08-24 15:58:43
【问题描述】:

是否可以覆盖模板类中的 -> 运算符并通过引用返回一些东西?

我看到了这个帖子:Overloading member access operators ->, .*

还有一个覆盖 -> 并通过引用返回的示例,但我无法让它与模板一起使用。这是我想要实现的一个小例子:

#include <iostream>

using namespace std;

class A
{
public:
    void do_something()
    {
        cout << "Hey there";
    }
};

template<class T>
class Ref
{
public:
    Ref(T* ptr)
    {
        objPtr = ptr;
    }

    // this is another alternative, but I don't want to write Get() every time I want to access the object
    T& get() { return *objPtr; }

    template <class T>
    Ref<T>& operator->() const { return *objPtr; }

    // doesn't work either
    //T& operator->() const { return *objPtr; }

    // this works as expected, but I really MUST return by reference
    //T* operator->() const { return objPtr; } 

private:
    T* objPtr;
};

int main()
{
    A myObj;
    Ref<A> ref(&myObj);

    // error C2675: unary '->': 'Ref<A>' does not define this operator or a conversion to a type acceptable to the predefined operator
    ref->do_something(); 

    return 0;
}

如何做到这一点?

【问题讨论】:

  • 为什么不返回一个指针? const T* operator-&gt;() const { return objPtr; }T* operator-&gt;() { return objPtr; }
  • 为什么要返回引用?您链接到的示例返回对还实现 operator-&gt; 并返回指针的对象的引用。重点是你仍然有一个指针。

标签: c++ templates operator-overloading


【解决方案1】:

如果返回引用,则不能在需要指针的ref-&gt;do_something(); 中使用它。您必须使用这种繁琐的方法:

ref.operator->().do_something(); 

而是返回一个指针 - 并将其设为 T*(或 const T*),而不是 Ref&lt;T&gt;*

例子:

#include <iostream>

class A {
public:
    void do_something() {
        std::cout << "Hey there\n";
    }
};

template<class T>
class Ref {
public:
    Ref(T& ptr) : objPtr(&ptr) {} // taking a T& but storing a pointer

    const T* operator->() const { return objPtr; }
    T* operator->() { return objPtr; }

private:
    T* objPtr;
};

int main() {
    A myObj;
    Ref<A> ref(myObj);

    ref->do_something(); 
}

【讨论】:

  • 或者,不存储指针,而是存储引用并在需要时将其转换为指针。 template&lt;class T&gt; class Ref { public: Ref(T&amp; obj) : objRef(obj) {} const T* operator-&gt;() const { return &amp;objRef; } T* operator-&gt;() { return &amp;obj; } private: T&amp; objRef; }; 但是当 std::reference_wrapper 存在时,这个 Ref 类似乎没有实际意义。
  • @RemyLebeau 是的,存储引用是一种选择,但会使复制/移动很痛苦,所以在这种情况下我更喜欢指针。
  • 这正是std::reference_wrapper 的意义所在——可存储、可复制/可移动、可重新分配的参考。
  • @RemyLebeau Yepp,我知道这一点。也许我应该在答案中添加一个关于它的注释,但我得到的印象是 OP 正在尝试学习如何做到这一点
猜你喜欢
  • 1970-01-01
  • 2013-06-10
  • 2018-12-07
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-08
  • 1970-01-01
相关资源
最近更新 更多