Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting an error, or at least a warning, when using a variable that has been std::move'ed elsewhere

This:

void foo(int &&r) {
  std::cout << r << std::endl;
}

int main() {
  int i = 2;
  foo(std::move(i));
  i = 3; //no warning. any way to get some warnings here?
  return 0;
}

Is there no way to tell the compiler to give me an error (or warning) if I accidentally use the variable after I have moved it? I think this would be very convenient. A lot of times I find myself moving variables elsewhere like that, but then I manually have to be VERY CAREFUL that I don't use them afterwards. Now this hasn't caused any problems yet, but who knows down the line... better be safe!

Maybe there are some preprocessor trickery (or pretty widely available compiler extensions) that exists to do this stuff?


More realistic example:

struct HugeStorage {
  std::vector<double> m_vec;
  HugeStorage(std::vector<double> vec) : m_vec(std::move(vec)) { }
};

struct SmallStorage {
  std::vector<double> m_vec;
  SmallStorage(std::vector<double> vec) : m_vec(std::move(vec)) { }
};

std::vector<double> vec_from_data_source() {
  return std::vector<double>(); //only example!!
}

int main() {
  std::vector<double> vec = vec_from_data_source();
  if (vec.size() > 10000)
  {
    HugeStorage storage(std::move(vec));
    //do some things, but I gotta be careful I don't do anything to vec
  }
  else
  {
    SmallStorage storage(std::move(vec));
    //do some things, but I gotta be careful I don't do anything to vec
  }
  return 0;
}
like image 407
user2015453 Avatar asked Feb 25 '13 19:02

user2015453


People also ask

What is the point of std:: move?

std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.

What happens to object after Std move?

The state of the moved object is defined by the move constructor. Hence it is ok to use it as long as the move constructor allows it. std::move just casts the object to T&& , it doesn't actually do anything to the object.

Should I always use std move?

Q: When should it be used? A: You should use std::move if you want to call functions that support move semantics with an argument which is not an rvalue (temporary expression).


1 Answers

//do some things, but I gotta be careful I don't do anything to vec

Clarification: You need to be careful that you don't do anything to vec that requires a precondition. You can do anything with vec that does not require any preconditions. For example you can assign vec a new value. You can call vec.clear(). You can call vec.size(). But do not call vec.pop_back() because that member function has a precondition.

like image 182
Howard Hinnant Avatar answered Sep 24 '22 11:09

Howard Hinnant