透明地将临时插入调用者的范围

时间:2015-02-18 16:24:46

标签: c++

在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的{​​{1}}被破坏时,它会将值重新覆盖回原始值。我的半优雅解决方案是让operator->隐藏arrow_helper,并在析构函数中使用T orig

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:0)

如果无法获取TT界面内的任何数据的引用或其他方式,我认为这应该是安全的。如果有任何方法可以获取这样的指针或引用,只要有人保存此类引用并稍后使用它,您就会完成并处于未定义的行为。