避免 const-overload 和 RVO 的代码重复

avoiding code duplication for const-overload and RVO

为了在处理const-overload时避免代码重复,我写了这样的东西:

#include <memory>

class A
{
    std::shared_ptr<int> _data;
public:
    const A lightCopy() const
    {
        A a;
        a._data = _data;
        return a;
    }

    A lightCopy()
    {
        using const_a_t = const A;
        const_a_t &const_me = *this;
        return const_me.lightCopy(); // const object here
    }
};

int main()
{
    A a;
    auto b = a.lightCopy();
}

const_cast 用于非 const 版本,否则它将是 const 方法中的非 const 函数调用,它可能会修改对象并且会在不被注意的情况下逃脱(因为 const_cast).从非 const 到 const 的 const 转换应该不会造成任何问题。

这里的问题是:因为我不能 const_cast 对象 — 是否有可能因为调用了 lightCopy() returns const 对象和实际 return type is not const — RVO 将不可能,并且将制作一个额外的副本?

根据 12.8 [class.copy] 第 31 段列表中的第三项,如果源和目标具有相同的 "cv-unqualified type",则允许​​复制省略临时对象:

when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move

也就是说,引用的代码复制省略允许的。

在原始示例中检测析构函数表明 clang, Intel's compiler, and EDG's frontend elide the copies while gcc 没有。也就是说,只有两个析构函数调用暗示所有可能的可删除副本都被删除了。副本被省略,与 b 的声明方式无关。我已经使用 autoAA const 声明了 b