标签: move-semantics

移动构造函数和静态数组

我一直在探索C++ 中Move Constructors的可能性,我想知道在下面的例子中有哪些方法可以利用这个功能.考虑以下代码:

template<unsigned int N>
class Foo {
public:
    Foo() {
        for (int i = 0; i < N; ++i) _nums[i] = 0;
    }

    Foo(const Foo<N>& other) {
        for (int i = 0; i < N; ++i) _nums[i] = other._nums[i];
    }

    Foo(Foo<N>&& other) {
        // ??? How can we take advantage of move constructors here?
    }

    // ... other methods and members

    virtual ~Foo() { /* no action required */ }

private:
    int _nums[N];
};

Foo<5> bar() …
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference move-constructor move-semantics c++11

26
推荐指数
3
解决办法
1万
查看次数

C++ 11移动构造函数


考虑以下类,实现移动构造函数的正确方法是什么:

class C {
public:
    C();
    C(C&& c);
private:
    std::string string;
}
Run Code Online (Sandbox Code Playgroud)

当然,这个想法是避免复制string或解除分配两次.
让我们假设基本的例子只是为了清晰,我确实需要一个移动构造函数.


我试过了:

C::C(C&& c) {
    //move ctor
    string = std::move(c.string);
}
Run Code Online (Sandbox Code Playgroud)

C::C(C&& c) : string(std::move(c.string)) {
    //move ctor
}
Run Code Online (Sandbox Code Playgroud)

两者都在gcc 4.8上编译正常并运行良好.这似乎选项A是正确的行为,string被复制,而不是使用选项B.移动
这是正确执行的举动构造的?

c++ move-semantics c++11

26
推荐指数
2
解决办法
1万
查看次数

移动分配与标准复制和交换不兼容

测试新的Move Semantics.

我刚刚问了一下移动构造函数我遇到的问题.但是,正如评论中所述,问题实际上是"移动分配"操作符和"标准分配"操作符在使用标准的"复制和交换"惯用法时发生冲突.

这是我正在使用的课程:

#include <string.h>
#include <utility>

class String
{
    int         len;
    char*       data;

    public:
        // Default constructor
        // In Terms of C-String constructor
        String()
            : String("")
        {}

        // Normal constructor that takes a C-String
        String(char const* cString)
            : len(strlen(cString))
            , data(new char[len+1]()) // Allocate and zero memory
        {
            memcpy(data, cString, len);
        }

        // Standard Rule of three
        String(String const& cpy)
            : len(cpy.len)
            , data(new char[len+1]())
        {
            memcpy(data, cpy.data, len);
        }
        String& operator=(String rhs)
        {
            rhs.swap(*this);
            return *this;
        } …
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics copy-and-swap c++11

26
推荐指数
2
解决办法
3995
查看次数

具有抑制移动构造/分配的类型如何仍被认为是可移动的?

struct copyable { // and movable
  copyable() = default;
  copyable(copyable const&) { /*...*/ };
  copyable& operator=(copyable const&) { /*...*/ return *this; }
};
Run Code Online (Sandbox Code Playgroud)

由于复制构造函数和复制赋值操作函数是显式定义的,因此它表示编译器不能隐式定义移动构造函数和移动赋值函数,因此不允许移动操作.

能告诉我上述理解是否正确吗?

c++ move-semantics c++11

26
推荐指数
1
解决办法
1630
查看次数

是否可以移动boost :: optional?

我一直试图在一个带有boost::optional成员变量的类中定义一个默认的移动构造函数.

#include <boost/optional.hpp>
#include <utility>
#include <vector>

struct bar {std::vector<int> vec;};

struct foo {
  foo() = default;
  foo(foo&&) = default;
  boost::optional<bar> hello;
};

int main() {
  foo a;
  foo b(std::move(a));
}
Run Code Online (Sandbox Code Playgroud)

我的编译器支持移动语义和默认的移动构造函数,但我不能让它工作.

% clang++ foo.cc -std=c++11 -stdlib=libc++
foo.cc:15:7: error: call to deleted constructor of 'foo'
  foo b(std::move(a));
      ^ ~~~~~~~~~~~~
foo.cc:9:3: note: function has been explicitly marked deleted here
  foo(foo&&) = default;
  ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

有没有办法移动a boost::optional 而不修改Boost的源代码?或者我应该等到Boost支持移动?

我过去遇到了同样的问题boost::any.

c++ boost move-semantics c++11 boost-optional

25
推荐指数
2
解决办法
6500
查看次数

内置类型有移动语义吗?

考虑以下代码:

#include <iostream>
using namespace std;

void Func(int&& i) {
    ++i;
}

int main() {
    int num = 1234;
    cout << "Before: " << num << endl;
    Func(std::move(num));
    cout << "After: " << num << endl;
}
Run Code Online (Sandbox Code Playgroud)

它的输出是:

Before: 1234
After: 1235
Run Code Online (Sandbox Code Playgroud)

显然,i正在内部进行修改Func,因为它i在被"转换"为r值引用之后被绑定到参数std::move.

好吧,我的观点:

移动对象意味着将资源的所有权从一个对象转移到另一个对象.但是,内置类型不包含资源,因为它们本身就是资源.转移他们持有的资源毫无意义.如示例所示,num修改了s值.它的资源,它的自我,是被修改的资源.

内置类型有移动语义吗?

另外,内置类型对象在移动后(如果是)是一个明确定义的行为吗?

c++ built-in-types move-semantics c++11

25
推荐指数
1
解决办法
5227
查看次数

移动语义和参数评估顺序

考虑以下因素:

std::string make_what_string( const std::string &id );

struct basic_foo
{
    basic_foo( std::string message, std::string id );
};

struct foo
    : public basic_foo
{
    foo::foo( std::string id)
        : basic_foo( make_what_string( id ), std::move( id ) ) // Is this valid?
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

因为C++中的参数评估顺序是未指定的,所以我想知道是否该行

basic_foo( make_what_string( id ), std::move( id ) )
Run Code Online (Sandbox Code Playgroud)

在上面的代码是有效的.

我知道这std::move只不过是一个演员,但什么时候执行std :: string move ctor?在评估完所有参数之后,是否应该调用基础构造函数?或者这是在评估参数期间完成的?换一种说法:

编译器是否这样做:

std::string &&tmp2 = std::move(id);
std::string tmp1 = make_what_string(id);
basic_foo(tmp1, tmp2);
Run Code Online (Sandbox Code Playgroud)

这是有效的.或这个:

std::string tmp2 = std::move(id);
std::string tmp1 = make_what_string(id);
basic_foo(tmp1, …
Run Code Online (Sandbox Code Playgroud)

c++ operator-precedence move-semantics c++11

25
推荐指数
2
解决办法
522
查看次数

C++ 11是否会移动语义来做一些新的事情,或者只是让语义更清晰?

我基本上想弄清楚,整个"移动语义"概念是一些全新的,还是只是让现有的代码更容易实现?我总是对减少调用复制/构造函数的次数感兴趣,但我通常使用引用(可能是const)传递对象,并确保我总是使用初始化列表.考虑到这一点(并考虑了整个丑陋的&&语法),我想知道是否值得采用这些原则或者只是按照我已经做的编码?这里有什么新东西要做,还是我已经做过的"更容易"的语法糖?

c++ optimization performance move-semantics c++11

25
推荐指数
3
解决办法
2847
查看次数

是否有使用prvalue的std :: forward的用例?

最常见的用法std::forward是,完美地转发转发(通用)引用,例如

template<typename T>
void f(T&& param)
{
    g(std::forward<T>(param)); // perfect forward to g
}
Run Code Online (Sandbox Code Playgroud)

param是一个lvalue,并std::forward最终将它转换为右值或左值,具体取决于与它有关的参数.

看一下cppreference.com定义,std::forward我发现还有一个rvalue重载

template< class T >
T&& forward( typename std::remove_reference<T>::type&& t );
Run Code Online (Sandbox Code Playgroud)

任何人都可以给我任何rvalue超载的理由吗?我看不到任何用例.如果你想将一个右值传递给一个函数,你可以按原样传递它,不需要std::forward在它上面应用.

这与std::move我不同,我明白为什么人们也想要一个rvalue重载:你可能会处理通用代码,在这些代码中你不知道你传递了什么,你想要无条件支持移动语义,请参阅例如为什么std ::移动采取普遍参考?.

编辑为了澄清这个问题,我问为什么从这里需要重载(2),以及它的用例.

c++ rvalue-reference move-semantics c++11

25
推荐指数
1
解决办法
844
查看次数

优化编译器可以添加std :: move吗?

如果编译器可以证明左值不会再次使用,它是否可以进行自动左值到右值转换?这是一个澄清我的意思的例子:

void Foo(vector<int> values) { ...}

void Bar() {
  vector<int> my_values {1, 2, 3};
  Foo(my_values);  // may the compiler pretend I used std::move here?
}
Run Code Online (Sandbox Code Playgroud)

如果将a std::move添加到注释行,则可以将矢量移动到Foo参数中,而不是复制.但是,正如所写,我没有使用std::move.

静态地证明my_values在注释行之后不会被使用,这很容易.那么编译器允许移动向量,还是需要复制它?

c++ optimization rvalue move-semantics c++11

25
推荐指数
1
解决办法
456
查看次数