【问题标题】:Visual studio not following moving semanticVisual Studio 不遵循移动语义
【发布时间】:2018-04-20 11:53:42
【问题描述】:

我正在 Visual Studio 2015 v4 中尝试此代码。

using namespace std;

void * operator new(size_t size) {
    cout << "Creating new " << endl;
    void * p = malloc(size);
    return p;
}


class CTest {
private:
    string a;
    string b;
public:
    CTest( const string &&one , const string && two  ) :a(move(one)), b(move(two)) {}
};


int main() {
    CTest("one", "one" );
    return 0;   
}

此代码在 Visual Studio 中输出 4 次“Creating new”,这意味着它分配了 4 次内存。但是按照语义,它应该只分配两次(在数据段中创建 2 个文字,创建一个和两个函数参数 = 2 个分配,然后将它们的资源移动到 a 和 b 成员变量)

在 g++ 下编译它会输出两次“Creating new”。

为了让 VS 遵循移动语义,我需要设置什么设置吗?据我所知,它应该是默认支持的。

感谢您的帮助。

【问题讨论】:

    标签: c++ visual-studio c++11 visual-studio-2015 move-semantics


    【解决方案1】:

    这里有几个问题:

    1) std::move 不动,尤其是当你经过const &amp;&amp; 时。查看答案herehere

    2) 我知道的每个std::string 实现都使用小缓冲区优化。当用短字符串(例如"one")构造时,此类实现将永远不会分配。

    3) 允许标准库运行时在静态初始化期间调用operator new,例如设置std::cout。您看到的分配很可能与 string 构造函数或(缺少)移动无关。

    【讨论】:

      【解决方案2】:

      参数onetwo 是对常量 std::string 对象的右值引用。如何从常量对象中移动?

      删除参数的const 限定符。在大多数情况下,使用 const 限定符对右值引用没有意义。

      或者不要使用 either const 或右值引用(无论如何编译器都应该创建正确的代码)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-29
        • 2017-07-26
        • 2018-09-17
        • 2022-10-24
        相关资源
        最近更新 更多