相关疑难解决方法(0)

C++ linux:错误:'move'不是'std'的成员如何绕过它?

所以在我的VS2010上我可以编译代码如下:

boost::shared_ptr<boost::thread> internal_thread;
boost::packaged_task<void> internal_task_w(boost::bind(&thread_pool::internal_run, this, internal_thread));
internal_thread = boost::shared_ptr<boost::thread>( new boost::thread(std::move(internal_task_w)));
Run Code Online (Sandbox Code Playgroud)

使用boost 1.47.0和linux ...前两行是正常的但是在std :: move它给出了error: ‘move’ is not a member of ‘std’.在VS2010上它不需要任何特殊标头.所以我想知道它在Linux上需要哪个头,无论如何它都在STD中吗?如果不是如何通过提升或其他东西绕过它?

c++ boost move std move-semantics

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

什么是std :: move的类型?

此代码按预期工作(在线).最后v是空的,w因为它已经窃取了内容,所以不是空的v.

    vector<int> v;
    v.push_back(1);
    cout << "v.size(): " << v.size() << endl;
    auto vp = move(v);
    vector<int> w(vp);
    cout << "w.size(): " << w.size() << endl;
    cout << "v.size(): " << v.size() << endl;
Run Code Online (Sandbox Code Playgroud)

但是,如果我取代auto vp=move(v)

    vector<int> && vp = move (v);
Run Code Online (Sandbox Code Playgroud)

然后它不动.相反,它复制,两个向量最后都是非空的.如图所示这里.

澄清:更具体地说,什么是自动衍生类型vp?如果不是vector<int> &&,那还有什么呢?为什么这两个例子虽然如此相似但却给出了不同的结果?

额外:我也试过这个,它仍然复制而不是移动

    std :: remove_reference< vector<int> > :: type && vp = move(v);
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics c++11

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

C++ - 将右值引用传递给函数?

我无法理解右值引用的工作原理。我有以下代码:

void f(int&& i)
{}

int main()
{
    int i = 42;
    int&& r = std::move(i);

    f(r);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这里,我收到以下编译器错误:

prog.cpp: In function ‘int main()’:
prog.cpp:46:7: error: cannot bind rvalue reference of type ‘int&&’ to lvalue of type ‘int’
     f(r);
       ^
prog.cpp:38:6: note:   initializing argument 1 of ‘void f(int&&)’
 void f(int&& i)
      ^
Run Code Online (Sandbox Code Playgroud)

当我显式声明r为右值引用时,为什么编译器认为我正在传递左值?这样做f(std::move(r))似乎有效,但我仍然不明白那里有什么不同。

这是因为在f(r)调用中r被视为左值吗?如果是,是什么类型的std::move(r)

c++

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

将右值传递给 std::move 并将右值引用绑定到它会在 ASAN 中生成 stack-use-after-scope 错误

考虑这个代码片段

#include <iostream>
int foo() {
  int a;
  return a;
}
int main() {
  auto &&ret = std::move(foo());
  std::cout << ret;
}
Run Code Online (Sandbox Code Playgroud)

使用ASAN编译g++ -fsanitize=address -fno-omit-frame-pointer -g -std=c++17 main.cpp -o main,运行./main显示错误

==57382==ERROR: AddressSanitizer: stack-use-after-scope on address 0x00016b3cb480 at pc 0x000104a37e68 bp 0x00016b3cb450 sp 0x00016b3cb448
READ of size 4 at 0x00016b3cb480 thread T0
    #0 0x104a37e64 in main main.cpp:8
    #1 0x104a75084 in start+0x200 (dyld:arm64e+0x5084)
Run Code Online (Sandbox Code Playgroud)

但是如果我在 auto 之后删除引用,这段代码可以编译并运行,而不会出现 ASAN 给出的错误。我不明白的是,如果std::move返回对给定对象的引用,那么该对象(foo()在本例中是临时创建的)将在函数调用返回后被销毁std::move,因此无论它是绑定到右值引用还是分配给新值应该无效,因为该临时值在移动操作后已经被销毁,对吗?那么为什么 ASAN 在第二种情况下不会给出错误。

- - …

c++ stdmove

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

传递给函数时使用 std::vector 误解移动语义

我试图理解移动语义的概念并做了一些测试。我有以下功能:

// testing the move semantic when passing 
// argument to be modified without copying

void process_copy( std::vector<int>&& aVec)
{
    std::cout << "Move semantic\n";
    aVec.push_back(42);
}
Run Code Online (Sandbox Code Playgroud)

现在在主要功能中,以下内容:

int main()
{
    std::vector<int> w_vec = {1,2,3,4,5};
    process_copy( std::move(w_vec));
}
Run Code Online (Sandbox Code Playgroud)

我希望w_vec现在是空的,因为我通过移动转换(将左值转换为右值)传递了它。但结果现在w_vec包含6 个元素(42 个已添加到向量中)。

我想念的东西?是std::vector可移动的物体吗?

c++ move move-semantics c++11

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

rvalue refs和std :: move

有人可以解释为什么B不编译,但C呢?我不明白为什么std :: move是必需的,因为变量已经是rvalue ref.

struct A {
  int x;
  A(int x=0) : x(x) {}
  A(A&& a) : x(a.x) { a.x = 0; }
};

struct B : public A {
  B() {}
  B(B&& b) : A(b) {}  // compile error with g++-4.7
};

struct C : public A {
  C() {}
  C(C&& c) : A(std::move(c)) {}  // ok, but why?
};
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference c++11

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

将std :: string删除它在析构函数中通过assign方法获取的内容

假设我有一个从自定义内存池分配的char*并填充了必要的数据.我在std :: string类的assign方法中使用了char*,并确保使用std :: move调用move varient.

void DoWork(char* my_pool_allocated_buffer) {
    std::string s;
    s.assign(std::move(my_pool_allocated_buffer));
    //do some work with s
}
Run Code Online (Sandbox Code Playgroud)

我有两个问题.

  1. 在方法结束时,std :: string析构函数是否会尝试删除通过assign获取的my_pool_allocated_buffer?文档说它只会删除它通过自己的分配器分配的内存.
  2. 方法退出后,my_pool_allocated_buffer将被其池释放.使用std :: move对此有什么影响吗?(假设池不关心缓冲区持有的实际数据).

c++ move stdstring c++11

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

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
查看次数

从 std::forward 赋值优于从 std::move 赋值的情况有哪些?为什么?

std::exchangecppreference.com上学习时,我遇到了下面粘贴的“可能的实现”。

  template<class T, class U = T>
  T exchange(T& obj, U&& new_value)
  {
      T old_value = std::move(obj);
      obj = std::forward<U>(new_value);
      return old_value;
  }
Run Code Online (Sandbox Code Playgroud)

obj = std::forward在赋值语句中看到而不是看起来有点奇怪std::move,我认为这会产生相同的效果。

我的理解是,这std::move等效于static_cast右值引用类型(但更具表现力)并始终返回 xvalue,而std::forward返回传递的相同值类型。

我的问题是为什么std:forward在上面的代码片段中使用?是否有一个简单的经验法则来决定何时这是更好的选择?

c++ move-semantics perfect-forwarding

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

在没有赋值的情况下调用 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
查看次数

防止在大型结构之间进行不必要的复制

我有巨大的结构 DataFrom 和 Data (实际上有不同的成员)。数据是从 DataFrom 创建的。

struct DataFrom{
    int a = 1;
    int b = 2;
};
static DataFrom dataFrom;   
struct Data{
    int a;
    int b;
};    
class DataHandler{
    public:
        static Data getData(const DataFrom& data2){
            Data data;
            setA(data, data2);
            setB(data, data2);
            return data;
        }
    private:
        static void setA(Data& dest, const DataFrom& source){
            dest.a = source.a;
        }
        static void setB(Data& dest, const DataFrom& source){
            dest.b = source.b;
        }
};
int main(){
    auto data = DataHandler2::getData(dataFrom); // copy of whole Data …
Run Code Online (Sandbox Code Playgroud)

c++ copy-elision c++17

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

为什么 `std::make_tuple` 需要移动语义?

std::tuple我认为通过std::make_tuplerequire 右值引用参数( type )创建一个非常有意识的设计决策T&&

然而,这意味着对象类型的移动语义 ( std::move 只不过是 to 的强制转换T&&,而且我对构建始终需要这样做的对象感到不太舒服std::tuple

int x = 7, y = 5;
std::tuple<int, int> fraction = make_tuple<int, int>( x, y ); // fails
Run Code Online (Sandbox Code Playgroud)

关于上述内容,编译器说:

错误 C2664: 'std::tuple<int,int> std::make_tuple<int,int>(int &&,int &&)': 无法将参数 1 从 'int' 转换为 'int &&'

message : 您无法将左值绑定到右值引用

std::tuple如果您不使用,则可以从左值制作 a没有问题make_tuple

std::tuple<int, int> fraction = { x, y }; // ok
Run Code Online (Sandbox Code Playgroud)

我的问题是,这是为什么?

c++ stdtuple

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