STL交换回报?

Rom*_*n L 8 c++ swap stl return-value-optimization

抱歉这么长的问题,但我尽量保持清醒.这在某种程度上遵循了我之前关于C++中的字符串的问题.我试图找出如何从没有冗余内存分配的函数返回std :: string,而不依赖于NRVO.我不想依赖NRVO的原因是:

  • 我们目前使用的编译器不支持它
  • 即使支持它也可能并不总是在调试模式下启用
  • 在某些情况下它可能会失败(例子)

请注意,我需要一个C++ 03兼容的解决方案(不幸的是没有C++ 0x rvalue引用......)

最简单的方法是传递引用并执行std :: swap,就像这样

void test(std::string& res)
{
    std::string s;
    //...
    res.swap(s);
}
Run Code Online (Sandbox Code Playgroud)

但是按价值返回比通过引用传递更自然且更方便,所以我想要实现的是:

std::string test()
{
    std::string s;
    //...
    return SOMETHING(s);
}
Run Code Online (Sandbox Code Playgroud)

理想情况下,它只会swap使用"返回值",但我不知道如何在C++中执行此操作.有auto_ptr已经移动而不是复制,我实际上可以使用auto_ptr<string>,但我想避免动态分配字符串对象本身.

我的想法是以某种方式"标记"一个字符串对象,它从函数返回以允许在返回时调用复制构造函数时移动其数据.所以我最终得到了这个代码,它完全符合我的要求:

struct Str
{
    struct Moveable
    {
        Str & ref;
        explicit Moveable(Str & other): ref(other) {}
    };

    Str() {}
    Str(const std::string& other) : data(other) {} // copy
    Str(Moveable& other) { data.swap(other.ref.data); } // move

    Moveable Move()
    {
        return Moveable(*this);
    }

    std::string data;
};

Str test()
{
    Str s;
    //...
    return s.Move(); // no allocation, even without NRVO
}
Run Code Online (Sandbox Code Playgroud)

所以......这一切都有意义,还是有一些我遗漏的严重问题?(例如,我不确定是否存在终身问题).也许你已经在图书馆(书,文章......)中看到过这样的想法,并且可以给我一个参考吗?

编辑:正如@rstevens注意到的,这段代码是特定于MSVC的,不会在不喜欢非const临时的g ++下编译.这一个问题,但我们假设这个实现是特定于MSVC的.

ybu*_*ill 4

boost 的实现在内部使用Boost.Thread等库的移动语义模拟。您可能想查看实现并执行类似的操作。

编辑:实际上,库Boost.Move正在积极开发中,因此您已经可以开始使用它了。