透明地将临时插入呼叫者的作用域

Transparently insert temporary into caller's scope

本文关键字:呼叫者 作用域 插入 透明      更新时间:2023-10-16

在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;

因为当来自第二个CCD_ 6的CCD_。我的半优雅解决方案是arrow_helper有一个隐藏的T orig,而assert(orig == *owner)在析构函数中。

不能保证所有更改都会被捕获:

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

如果无法通过T的接口或其他方式获取对T中任何数据的引用,我认为这应该是安全的。如果有任何方法可以获取这样的指针或引用,那么一旦有人保存了这样的引用并在以后使用它,您就完成了,并且处于未定义的行为中。