标签: move-semantics

使用指针时的 C++ 移动语义

move使用原始指针时如何使用赋值运算符。

除了这样做之外还有其他方法吗:

void Function(T* dest)
{
    T* src = LoadT();
    (*dest) = std::move(*src);
    delete src;
}
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics

0
推荐指数
1
解决办法
3269
查看次数

如果代码更改为 std::move(vector) 将在此函数中保存复制操作

该功能是将文件内容提取到向量中,如下所示:

std::vector<uint8_t> GetFileContents(const std::string& filename)
{
    std::ifstream file(filename, std::ios::binary);
    if (!file.good())
    {
        return {};
    }
    file.seekg(0, std::ios::end);
    std::streampos fileSize = file.tellg();
    file.seekg(0, std::ios::beg);

    std::vector<uint8_t> fileData(fileSize);
    file.read((char*) &fileData[0], fileSize);
    return fileData;
}
Run Code Online (Sandbox Code Playgroud)

就行:

std::vector<uint8_t> fileData(fileSize);
file.read((char*) &fileData[0], fileSize);
return fileData;
Run Code Online (Sandbox Code Playgroud)

fileData 向量被复制到一个临时向量中以在此处返回?

我需要更改为:

std::vector<uint8_t> fileData(fileSize);
file.read((char*) &fileData[0], fileSize);
return std::move(fileData);
Run Code Online (Sandbox Code Playgroud)

进行移动并保存矢量复制操作?

支持移动的功能还需要进行其他更改吗?

对于空的情况, std::move({}) 有任何价值吗?

c++ move-semantics

0
推荐指数
1
解决办法
69
查看次数

使用 std::move 和在数字上加 0 之间的区别?

我很好奇,使用std::move将左值整数转换为右值与0向该整数添加 a 之间有什么实际区别吗?或任何其他中性算术运算(乘以1、减去0等)。

添加0

int f(int&& i){
    i++;
    return i;
}


int main(){
    int x = 43;
    f(x+0);
}
Run Code Online (Sandbox Code Playgroud)

使用std::move

#include <iostream>

int f(int&& i){
    i++;
    return i;
}


int main(){
    int x = 43;
    f(std::move(x));
}
Run Code Online (Sandbox Code Playgroud)

我知道我们不能对所有类型执行这种中立的操作,但我的问题特别是关于整数而不是其他类型。

c++ rvalue-reference move-semantics

0
推荐指数
1
解决办法
225
查看次数

当底层元素被移动后,迭代器仍然有效吗?

如果我有一个迭代器指向 STL 容器中的一个元素,并且我用迭代器移动了该元素,那么标准是否保证迭代器仍然有效?我可以将它与容器的方法一起使用吗container::erase

容器是连续容器(例如 )vector还是非连续容器(例如 )也很重要吗list

std::list<std::string> l{"a", "b", "c"};
auto iter = l.begin();
auto s = std::move(*iter);
l.erase(iter);       // <----- is it valid to erase it, whose underlying element has been removed?
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics c++11

0
推荐指数
1
解决办法
238
查看次数

在遗留 C++ 类中实现移动语义

我正在开发一个遗留应用程序,其类的名称Point3D如下所示......

template <class T>
class Point3D final
{
    T values[3];
public:
    Point3D();
    Point3D(T x, T y, T z);
    explicit Point3D(const T value);
    Point3D(const Point3D& point);
    explicit Point3D(const Point2D<T>& point);
    ~Point3D();
};
Run Code Online (Sandbox Code Playgroud)

这个类在很多地方都被用作vector<Point3D<double>>. 向量的大小为 > 10^5。此外,遗留代码将此向量作为值传递并按值返回。这使得应用程序非常慢。同样在很多地方,我们都有类似的代码,如下所示......

for(auto i: n){ // This loop runs for 10^4 times
    Point3D<double> vpos;

    vpos[X_COORDINATE] = /*Some calculation*/;
    vpos[Y_COORDINATE] = /*Some calculation*/;
    vpos[Z_COORDINATE] = /*Some calculation*/;

    Positions.push_back(vpos);
}
Run Code Online (Sandbox Code Playgroud)

为了提高性能,我计划修改Point3D要使用的类,move semantics如下所示......

template <class T> 
class Point3D final {
    T* …
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics c++11

0
推荐指数
1
解决办法
148
查看次数

移动构造函数/运算符=

我正在尝试学习C++的新功能,即移动构造函数和赋值X::operator=(X&&),我发现了一些有趣的例子, 但我唯一不理解但更不同意的是移动ctor和赋值运算符中的一行(在下面的代码中标记):

MemoryBlock(MemoryBlock&& other)
   : _data(NULL)
   , _length(0)
{
   std::cout << "In MemoryBlock(MemoryBlock&&). length = " 
             << other._length << ". Moving resource." << std::endl;

   // Copy the data pointer and its length from the 
   // source object.
   _data = other._data;
   _length = other._length;

   // Release the data pointer from the source object so that
   // the destructor does not free the memory multiple times.
   other._data = NULL;
   other._length = 0;//WHY WOULD I EVEN BOTHER TO SET IT …
Run Code Online (Sandbox Code Playgroud)

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

-1
推荐指数
1
解决办法
1497
查看次数

Visual Studio不遵循移动语义

我在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;   
}
Run Code Online (Sandbox Code Playgroud)

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

在g ++下编译它会两次输出"Creating new",就像它应该的那样.

我需要设置任何设置才能使VS遵循移动语义吗?据我所知,它应默认支持.

感谢帮助.

c++ visual-studio move-semantics c++11 visual-studio-2015

-1
推荐指数
1
解决办法
60
查看次数

为什么即使迭代器是 std::move_iterator,ranges-v3 也不移动元素?

#include <range/v3/all.hpp>
#include <vector>
#include <string>
#include <deque>

using namespace std::literals;

int main()
{
    auto src         = std::vector{"123"s, "456"s, "789"s};
    auto movable_rng = ranges::subrange(
                           std::make_move_iterator(src.begin()), 
                           std::make_move_iterator(src.end()));

    auto dst = ranges::to<std::deque<std::string>>(movable_rng);

    for (auto e : src)
    {
        std::cout << e << std::endl;
    }

    for (auto e : dst)
    {
        std::cout << e << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

用 libc++ 用 clang 10 编译,输出为:

123
456
789
123
456
789
Run Code Online (Sandbox Code Playgroud)

正如我所料,结果应该是:

""
""
""
123
456
789
Run Code Online (Sandbox Code Playgroud)

为什么即使是迭代器,ranges-v3 也不移动元素 std::move_iterator

========更新======

我的范围版本是: …

c++ standards rvalue-reference move-semantics range-v3

-1
推荐指数
1
解决办法
135
查看次数

c ++:关于转发引用的混淆

我看了这个约(令人难以置信的好写的)文章转发参考用C斯科特迈尔斯++ 11.

现在,重点关注本文的这一部分:

template <class... Args>
void emplace_back(Args&&... args); // deduced parameter types ? type deduction;
...                                // && ? universal references
Run Code Online (Sandbox Code Playgroud)

因此,与其他情况相比,省略号不会&&成为右值引用,但它仍然是通用引用.

根据我的理解,当我们有通用引用时,我们可以调用函数传递rvalue和lvalues(哇,太酷了!)

现在,我已经实现了这个功能:

template <typename ReturnType, typename... Args>
ReturnType callFunction(MemFunc<ReturnType, Args...> memFunc, Args&& ... args) { ...
Run Code Online (Sandbox Code Playgroud)

因此(使用与前一示例相同的逻辑)&&意味着转发引用.

如果我试着打电话:

typedef vector<double> vecD;
vecD vec;
mem.callFunction<vecD, vecD>(sortFunc, vec);
Run Code Online (Sandbox Code Playgroud)

编译器会抱怨 You cannot bind an lvalue to an rvalue reference

为什么会这样?

整个代码:

#include <functional>
#include <vector>

using namespace std;
struct MultiMemoizator { …
Run Code Online (Sandbox Code Playgroud)

c++ move move-semantics c++11 forwarding-reference

-2
推荐指数
1
解决办法
410
查看次数

使用移动构造函数与传递指针的优势是什么?

Foo(Foo&& other) {
  this->bar = other.bar;
  other.bar = nullptr;
}

Foo(Foo* other) {
  this->bar = other->bar;
  other->bar = nullptr;
}
Run Code Online (Sandbox Code Playgroud)

上面两个似乎只是在做同样的事情。那么为什么推荐使用移动构造函数呢?它提供了哪些优势?

c++ constructor move move-semantics

-2
推荐指数
1
解决办法
600
查看次数