C ++ 11的&&(R值参考)运算符淘汰了“代理对象"设计模式? [英] Does C++11's && (R-value reference) operator obsolete the 'proxy-object' design-pattern?

查看:49
本文介绍了C ++ 11的&&(R值参考)运算符淘汰了“代理对象"设计模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Scott Meyers的项目30 更有效的C ++"绘制出一个代理对象"编程设计模式.

Item 30 of Scott Meyers' "more effective C++" maps out a 'proxy object' programming design-pattern.

问题是,如果您有:

X x;
x[3]=42; 
cout<<x[3]

...您需要X的operator []重载才能区分使用L值和R值.

... you need X's operator[] overload to be able to distinguish between L-value and R-value use.

(也许您需要运行不同的代码,例如,在第一种情况下,可能涉及大量复制,但在第二种情况下,我们可以只传递参考).

代理模式是X包含Proxy类,并且X的operator []重载返回Proxy类型的对象.

The proxy pattern is that X contains a Proxy class, and X's operator[] overloads return an object of type Proxy.

该代码变为:

X x;
{some Proxy object}=42; 
cout<<{some Proxy object}

现在,我们只需要为Proxy对象提供对"operator =的覆盖,即可处理第一种情况,而对'转换为std :: string或char *'的覆盖即可处理第二种情况.

Now we just have to give our Proxy object an override for "operator=", which handles the first case, and an override for 'conversion to std::string or char*' which handles the second.

C ++尝试寻找合适的类型转换将触发相关的覆盖.

And C++'s attempt to find an appropriate type conversion will trigger the relevant override.

但是,这本书是在C ++ 11之前编写的,而C ++ 11的主要功能之一是新的&&(R值参考)运算符.

However, this book was written before C++11, and one of the main features of C++11 is a new && (R-value reference) operator.

现在是否有一种更简单的编码单独的R值和L值分配的方法?

Is there now a simpler way of coding separate R-value and L-value assignments?

此代理对象设计模式现在已过时吗?

Is this proxy-object design-pattern now obsolete?

推荐答案

不,我认为这里还没有其他机制.

No, I don't believe there is yet an alternative mechanism here.

尽管使用ref限定的方法在某些情况下可以提供不同的行为,但是将根据调用它们的对象的状态来解决重载.对于返回的对象的用法,它们并没有解决.

While ref-qualified methods can provide different behavior in certain scenarios, the overloads are resolved based on the status of the object they were invoked upon. They are not resolved on the usage of the object that they return.

在下面的实时示例中,我围绕创建了一个包装器std :: vector ,尝试在分配给索引时自动增长向量,并在仅从索引读取时允许未定义的行为.

In the following live example, I create a wrapper around a std::vector, attempting to auto-grow the vector when assigning into an index and allowing undefined behavior when merely reading from an index.

但是这种方式不起作用:

But it doesn't work that way:

template <typename T>
struct AutoVector
{
    std::vector<T> m_vec;
    AutoVector() { m_vec.resize(1); }

    T& operator[](const size_t index) &
    {
        std::cout << "Inside operator[" << index << "]&\n";
        if (m_vec.size() < index)
            m_vec.resize(index);
        return m_vec[index];
    }

    T operator[](const size_t index) &&
    {
        std::cout << "Inside operator[" << index << "]&&\n";
        return m_vec[index];
    }
};

如果通过以下方式调用此方法,则两者都将调用左值限定的 operator []& :

If this is invoked the following ways, both will invoke the lvalue-qualified operator[] &:

AutoVector<int> avec;
avec[4] = 6;
std::cout << avec[4] << "\n";

    --> Inside operator[4]&
    --> Inside operator[4]&
    --> 6

如果这是在临时调用的,则可以调用右值限定的 operator []&& :

If this is invoked on a temporary, it can invoke the rvalue-qualified operator[] &&:

std::cout << AutoVector<int>()[0] << "\n";

    --> Inside operator[0]&&
    --> 0

这没有所需的行为.对 operator [] 返回的代理对象进行相同类型的测试通常会导致它在所有情况下都调用rvalue限定的方法,除非捕获并命名了代理.它仍然不能反映代理的使用方式.

This does not have the desired behavior. Applying the same sort of test to a proxy object returned by operator[] would typically result in it calling the rvalue-qualified methods in all cases, unless the proxy was captured and named. It would still not reflect how the proxy was used.

这篇关于C ++ 11的&amp;&amp;(R值参考)运算符淘汰了“代理对象"设计模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆