Edit:
So the real question was why does it throws an error.
std::out_of_range exception is thrown when an index that is not in the range of the container is accessed.
As mentioned in the comments the problem lies in while(str.find(' ')>=0). string::find returns string::npos when it finds nothing.
string::npos is defined as -1, but since it's a size_t type, it can't be less that 0. So instead the value is the largest possible unsigned int because it "loops" on its type.
So it will be 4294967295, or whatever value is the maximum for a size_t type on your system and with your compilation flags.
Back to the problem while(str.find(' ')>=0), as said the return of str.find will always be a positive value, so you never stop looping and finally get an std::out_of_rangeexception because you try to access str[string::npos] which is not possible.
The "better' while would then be: while(str.find(' ') != string::npos)
Initial answer:
There is another way to do this using std::remove algorithm. It provides a range to std::erase.
#include <iostream>    
#include <string>
#include <algorithm>
int main()
{
    std::string str = "this is a line";
    std::cout << "before: " << str << std::endl;
    str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
    std::cout << "after: " << str << std::endl;
}