标签: move-semantics

什么时候在C++ 11中制作一个不可移动的类型?

我很惊讶这没有显示在我的搜索结果中,我认为有人会在之前问过这个,考虑到C++ 11中移动语义的用处:

我什么时候必须(或者对我来说是个好主意)在C++ 11中创建一个不可移动的类?

(原因比与现有代码的兼容性问题,那是.)

c++ c++-faq move-semantics c++11

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

移动赋值运算符和`if(this!=&rhs)`

在类的赋值运算符中,通常需要检查所分配的对象是否是调用对象,这样就不会搞砸了:

Class& Class::operator=(const Class& rhs) {
    if (this != &rhs) {
        // do the assignment
    }

    return *this;
}
Run Code Online (Sandbox Code Playgroud)

移动赋值运算符需要相同的东西吗?是否有过这样的情况this == &rhs

? Class::operator=(Class&& rhs) {
    ?
}
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics c++11 move-assignment-operator

117
推荐指数
3
解决办法
4万
查看次数

无法摆脱借来的内容

我不明白这个错误cannot move out of borrowed content.我收到了很多次,我总是解决它,但我从来没有理解为什么.

例如:

for line in self.xslg_file.iter() {
    self.buffer.clear();

    for current_char in line.into_bytes().iter() {
        self.buffer.push(*current_char as char);
    }

    println!("{}", line);
}
Run Code Online (Sandbox Code Playgroud)

产生错误:

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:31:33
   |
31 |             for current_char in line.into_bytes().iter() {
   |                                 ^^^^ cannot move out of borrowed content
Run Code Online (Sandbox Code Playgroud)

我通过克隆解决了这个问题line:

error[E0507]: cannot move out of `*line` which is behind a shared reference
  --> src/main.rs:31:33
   |
31 |             for current_char in line.into_bytes().iter() {
   |                                 ^^^^ …
Run Code Online (Sandbox Code Playgroud)

reference move-semantics rust borrow-checker

115
推荐指数
2
解决办法
6万
查看次数

在基于范围的for循环中使用通用引用有什么好处?

const auto&如果我想执行只读操作就足够了.但是,我已经碰到了

for (auto&& e : v)  // v is non-const
Run Code Online (Sandbox Code Playgroud)

最近几次.这让我想知道:

是否有可能在一些不起眼的角落情况下,存在使用通用引用一些性能优势,相比auto&还是const auto&

(shared_ptr是一个晦涩角落案件的嫌疑人)


更新 我在收藏夹中找到的两个示例:

迭代基本类型时使用const引用的任何缺点?
我可以使用基于范围的for循环轻松迭代地图的值吗?

请专注于一个问题:我为什么要在使用自动&&范围为基础的for循环?

c++ performance for-loop move-semantics c++11

111
推荐指数
3
解决办法
2万
查看次数

何时应该在函数返回值上使用std :: move?

在这种情况下

struct Foo {};
Foo meh() {
  return std::move(Foo());
}
Run Code Online (Sandbox Code Playgroud)

我很确定移动是不必要的,因为新创建的Foo将是一个xvalue.

但在这种情况下呢?

struct Foo {};
Foo meh() {
  Foo foo;
  //do something, but knowing that foo can safely be disposed of
  //but does the compiler necessarily know it?
  //we may have references/pointers to foo. how could the compiler know?
  return std::move(foo); //so here the move is needed, right?
}
Run Code Online (Sandbox Code Playgroud)

我认为需要采取行动吗?

c++ move-semantics c++11

109
推荐指数
4
解决办法
5万
查看次数

为什么我们复制然后移动?

我看到某个地方有人决定复制一个对象并随后将其移动到一个类的数据成员的代码.这使我感到困惑,因为我认为移动的重点是避免复制.这是一个例子:

struct S
{
    S(std::string str) : data(std::move(str))
    {}
};
Run Code Online (Sandbox Code Playgroud)

这是我的问题:

  • 为什么我们不采用右值引用str
  • 副本不会很贵,特别是给出类似的东西std::string吗?
  • 作者决定复制然后移动的原因是什么?
  • 我应该什么时候自己做?

c++ move-semantics c++11

97
推荐指数
4
解决办法
7736
查看次数

std :: move()如何将值传递给RValues?

我发现自己并没有完全理解它的逻辑std::move().

起初,我用谷歌搜索它,但似乎只有关于如何使用的文件std::move(),而不是它的结构如何工作.

我的意思是,我知道模板成员函数是什么,但是当我std::move()在VS2010中查看定义时,它仍然令人困惑.

std :: move()的定义如下.

template<class _Ty> inline
typename tr1::_Remove_reference<_Ty>::_Type&&
    move(_Ty&& _Arg)
    {   // forward _Arg as movable
        return ((typename tr1::_Remove_reference<_Ty>::_Type&&)_Arg);
    }
Run Code Online (Sandbox Code Playgroud)

首先对我来说奇怪的是参数,(_Ty && _Arg),因为当我调用函数时,如下所示,

// main()
Object obj1;
Object obj2 = std::move(obj1);
Run Code Online (Sandbox Code Playgroud)

它基本上等于

// std::move()
_Ty&& _Arg = Obj1;
Run Code Online (Sandbox Code Playgroud)

但正如您已经知道的那样,您不能直接将LValue链接到RValue引用,这让我觉得它应该是这样的.

_Ty&& _Arg = (Object&&)obj1;
Run Code Online (Sandbox Code Playgroud)

但是,这是荒谬的,因为std :: move()必须适用于所有值.

所以我想要完全理解它是如何工作的,我也应该看看这些结构.

template<class _Ty>
struct _Remove_reference
{   // remove reference
    typedef _Ty _Type;
};

template<class _Ty>
struct _Remove_reference<_Ty&>
{   // remove reference
    typedef _Ty _Type;
}; …
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics c++11

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

是一个`= default`移动构造函数,等同于成员移动构造函数吗?

这是

struct Example { 
    int a, b; 
    Example(int mA, int mB) : a{mA}, b{mB}               { }
    Example(const Example& mE) : a{mE.a}, b{mE.b}        { }
    Example(Example&& mE) : a{move(mE.a)}, b{move(mE.b)} { }
    Example& operator=(const Example& mE) { a = mE.a; b = mE.b; return *this; } 
    Example& operator=(Example&& mE)      { a = move(mE.a); b = move(mE.b); return *this; } 
}
Run Code Online (Sandbox Code Playgroud)

相当于此

struct Example { 
    int a, b; 
    Example(int mA, int mB) : a{mA}, b{mB} { }
    Example(const Example& mE)            = default; …
Run Code Online (Sandbox Code Playgroud)

c++ constructor default move-semantics c++11

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

我可以列出 - 初始化只移动类型的向量吗?

如果我通过我的GCC 4.7快照传递以下代码,它会尝试将unique_ptrs 复制到向量中.

#include <vector>
#include <memory>

int main() {
    using move_only = std::unique_ptr<int>;
    std::vector<move_only> v { move_only(), move_only(), move_only() };
}
Run Code Online (Sandbox Code Playgroud)

显然,因为std::unique_ptr不可复制而无法工作:

错误:使用已删除的函数'std :: unique_ptr <_Tp,_Dp> :: unique_ptr(const std :: unique_ptr <_Tp,_Dp>&)[with _Tp = int; _Dp = std :: default_delete; std :: unique_ptr <_Tp,_Dp> = std :: unique_ptr]'

GCC是否正确尝试从初始化列表中复制指针?

c++ initializer-list move-semantics c++11

89
推荐指数
4
解决办法
1万
查看次数

initializer_list和移动语义

我允许将元素移出std::initializer_list<T>

#include <initializer_list>
#include <utility>

template<typename T>
void foo(std::initializer_list<T> list)
{
    for (auto it = list.begin(); it != list.end(); ++it)
    {
        bar(std::move(*it));   // kosher?
    }
}
Run Code Online (Sandbox Code Playgroud)

由于std::intializer_list<T>需要特殊的编译器注意并且没有像C++标准库的普通容器那样的值语义,所以我宁愿安全而不是抱歉并且问.

c++ templates initializer-list move-semantics c++11

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