在C++中,operator->具有特殊的语义,即如果返回的类型不是指针,它将再次对该类型调用operator->。但是,中间值被调用表达式保留为临时值。这允许代码检测返回值的变化:

template<class T>
class wrapper
{
    // ...
    T val;

    struct arrow_helper
    {
        arrow_helper(const T& temp)
            : temp(temp){}
        T temp;
        T* operator->() { return &temp; }
        ~arrow_helper() { std::cout << "modified to " << temp << '\n'; }
    };

    arrow_helper operator->() { return{ val }; }
    //return const value to prevent mistakes
    const T operator*() const { return val; }
}

然后可以透明地访问T的成员:
wrapper<Foo> f(/*...*/);
f->bar = 6;

这样做有什么可能出问题吗?另外,有没有一种方法可以使用operator->以外的功能来获得这种效果?

编辑:我遇到的另一个问题是像这样的表达式
f->bar = f->bar + 6;

因为当第二个arrow_helper中的operator->被破坏时,它会将值重新覆盖为原始值。我的半优雅解决方案是让arrow_helper具有隐藏的T orig和析构函数中的assert(orig == *owner)

最佳答案

无法保证会捕获所有更改:

Foo &x = f->bar;
x = 6; /* undetected change */

关于c++ - 透明地将临时插入到调用者的作用域中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28588537/

10-11 22:24
查看更多