标签: stdmove

为什么C++编译器不能在传值方案中优化更多字符串结构?

(这个问题的灵感来自Nicolai Josuttis的CppCon 2017演讲.)

考虑以下源文件(对于对象,而不是完整的程序):

#include <string>

class C {
    std::string s_;
public:
    C(std::string s) : s_(s) { };
    void bar();
};

void foo() {
    std::string hello { "The quick brown fox jumped over the lazy dog" };
    C c { hello };
    c.bar();
}
Run Code Online (Sandbox Code Playgroud)

它的编译结果在GodBolt上.

即使使用-O2(甚至使用-O3),似乎字符串构造函数被调用三次.具体而言,s构造,仅用于构造s_,然后被破坏.我的问题:

  • 是否允许编译器简单地s_从ctor的参数构造,而不是构造s
  • 如果没有,则编译器允许移动,构建s_s,看到后者是如何闲置?
  • 如果之前的任何答案都是"是" - 为什么gcc和clang不这样做?
  • 如果s构造正确,编译器不能避免构造hello,看看它没有其他用途吗?或者至少离开它?

c++ stdstring compiler-optimization copy-elision stdmove

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

我应该更改使用push_back来使用std :: move的代码吗?

我刚刚阅读了关于rvalue引用的内容,下面是我所指的代码

vector<string> v;
string s = "hello";   

v.push_back(s); 
cout << s << endl;
cout << v[0] << endl;
return 0
Run Code Online (Sandbox Code Playgroud)

我的问题是,到目前为止,每当我看到对象(或字符串)的向量时,我主要看到插入操作如上所述.相反,如果我这样做,v.push_back(std::move(s))那么我不会不必要地创建重复的对象.

这应该是向STL添加对象的正确方法,我们关心的只是容器中的数据而不是其他变量.

c++ stl stdmove

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

从标准容器中移动元素是否合法?

我正在编写一个类,该类需要用于过滤成员容器的高效函数(可以说std::vector)。此功能应具有类似于以下内容的界面:

void filter(std::vector<SomeType>& items, const std::vector<int>& inds);
Run Code Online (Sandbox Code Playgroud)

该函数应使容器items处于以下状态:-索引所指向的项目inds应被删除-其他项目应保留在容器中并保持初始顺序。

为简单起见,假设这inds是一个完美的容器,每个操作均带有O(1),并且所有索引均有效且无重复。

我的想法是创建第二个容器,保留所需的空间,然后将std::move所有未索引的元素(通过)移动inds到该新容器中;然后只需交换旧容器和新容器即可。

例如这样:

void filter(std::vector<SomeType>& items, const std::vector<int>& inds)
{
    std::vector<SomeType> new_items{};
    new_items.reserve( items.size() - inds.size() );

    for(size_t i = 0; i < items.size(); ++i)
        if( contains( inds, i ) ) // magic O(1) function, never mind
            new_items.push_back( std::move( items[i] ) );

    items.swap(new_items);
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

1)在(或其他标准容器)std::move内部的某个元素上使用后,vector是否会出现诸如双重破坏这些元素的问题?

2)是否有标准方法可以有效地进行此类过滤?

c++ containers stdmove

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

std::move 一个将被覆盖的变量

我跑了一些代码

template<class InputIt, class T>
constexpr // since C++20
T accumulate(InputIt first, InputIt last, T init)
{
    for (; first != last; ++first) {
        init = std::move(init) + *first; // std::move since C++20
    }
    return init;
}
Run Code Online (Sandbox Code Playgroud)

我有个问题。为什么我们必须使用 std::move oninit即使initint

c++ stdmove

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

std::move 如何使原始变量的值无效?

cpp 参考中的以下示例中:

#include <iostream>
#include <utility>
#include <vector>
#include <string>

int main()
{
    std::string str = "Hello";
    std::vector<std::string> v;

    // uses the push_back(const T&) overload, which means 
    // we'll incur the cost of copying str
    v.push_back(str);
    std::cout << "After copy, str is \"" << str << "\"\n";

    // uses the rvalue reference push_back(T&&) overload, 
    // which means no strings will be copied; instead, the
    // Contents of str will be moved into the vector.  This is
    // less …
Run Code Online (Sandbox Code Playgroud)

c++ move move-semantics c++11 stdmove

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

为什么当构造函数引用字符串时没有正确打印?

我有以下代码,当它的析构函数被调用时它没有打印正确的字符串

struct Tracer {

 Tracer( const std::string& name_in)
 : name{ name_in } {
  std::cout << name << " constructed.\n";
 }

~Tracer() {
 std::cout << name << " destructed.\n";
}

private:

const std::string& name;
};

Tracer static_tracer{ "static Tracer" };

int main() {

}
Run Code Online (Sandbox Code Playgroud)

输出:构造的静态 Tracer。

?1?问?

但以下代码按预期工作:

Tracer( std::string name_in)
 : name{ std:move(name_in) } {
 std::cout << name << " constructed.\n";
 }

private:
std::string name;
Run Code Online (Sandbox Code Playgroud)

输出:构造的静态 Tracer。

静态示踪剂被破坏。

或者当使用 stringview 或简单的 sting 时。

我们是如何在第一个代码中的程序终止期间丢失对字符串的引用的?

我们也不应该使用 move() 来释放对字符串的引用,因为它有一个构造函数作用域吗?

谢谢!

c++ string reference c++17 stdmove

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

为什么 std::move 不会在默认移动构造函数中将源变量更改为默认值?

我试图理解移动构造函数。

我在类的构造函数中分配内存并在析构函数中销毁它。

当我尝试移动类时,我仍然有一个双空闲。

#include <algorithm>

class TestClass
{
 public:
  TestClass() {a_ = new int[1];}
  TestClass(TestClass const& other) = delete;
  TestClass(TestClass && other) noexcept // = default;
  {
    this->a_ = std::move(other.a_);
  }
  ~TestClass() {delete[] a_;}
 private:
  int* a_ = nullptr;
};

int main( int argc, char** argv )
{
  TestClass t;
  TestClass t2 = std::move(t);
}
Run Code Online (Sandbox Code Playgroud)

为什么std::move不改为 nullptr other.a_

如果移动构造函数是默认的,我也有同样的问题。

我发现了以下问题,但我仍然不知道为什么移动运算符不将源变量更改为默认值。

std::move 如何使原始变量的值无效?

C++如何将对象移动到nullptr

C++ std::move 一个指针

c++ move-semantics c++11 stdmove

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

std::move(const shared_ptr 引用) 是什么意思?

以下是我正在尝试的玩具代码...我理解第一个和第二个。第一个将所有权授予_p. 第二个复制p_p. 但第三个我没看懂……

std::move的是什么const shared_ptr &意思?谢谢。

class P { };

class A {
public:
    // first one
    A(std::shared_ptr<P> &p, int) : _p(std::move(p))
    {
        std::cout << "1st Ctor: "
                  << p.use_count() << ", " << _p.use_count() << std::endl;
    }

    // second one
    A(const std::shared_ptr<P> &p, std::string) : _p(p)
    {
        std::cout << "2nd Ctor: "
                  << p.use_count() << ", " << _p.use_count() << std::endl;
    }

    // third one
    A(const std::shared_ptr<P> &p) : _p(std::move(p)) …
Run Code Online (Sandbox Code Playgroud)

c++ shared-ptr move-semantics c++11 stdmove

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

std::move 可以移动内置类型或 C 指针或数组吗

我有 3 个问题:

  1. 可以std::move移动内置类型吗?
int a = 10;
int b = std::move(a);
Run Code Online (Sandbox Code Playgroud)

a是无效值吗?


  1. 可以std::move移动指针
int *a = new int[10];
int *b = std::move(a);
Run Code Online (Sandbox Code Playgroud)

a变成无效指针还是nullptr


  1. 可以std::move移动ac阵列吗?
struct S {
  int array[10];
}
S a;
for(int i=0; i<10; i++)
  a.array[i]=1;
S b;
b = std::move(a);
Run Code Online (Sandbox Code Playgroud)

a.array变成无效数组吗?

c++ c++11 stdmove

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

在没有赋值的情况下调用 std::move() 会发生什么

当我在std::move没有任何分配的情况下使用时会发生什么?

std::string s = "Moving";
std::move(s);  //What happens on this line to s?
//is s still valid here?
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics c++11 stdmove

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