I'd like to start by saying that yes, I Google'd this problem before coming here, and none of the answers seemed relevant.
I stole the below code from What's the best way to trim std::string?, because for whatever reason, there is no standard c++ trim function. Using Visual Studio, it compiled fine, and I managed to complete the rest of the project without it giving me any errors.
This morning though, I decided to try compiling the entire project manually (using g++ -std=c++11 *.cpp), and now suddenly the trim functions are yielding the following error:
DVD.cpp: In static member function 'static DVD DVD::parseDVD(std::string, std::string)':
DVD.cpp:65:59: error: invalid initialization of non-const reference of type 'std::string& {aka std::basic_string<char>&}
 from an rvalue of type 'std::basic_string<char>'
 std::string rID = trim(dataStr.substr(0, preTitlePos - 1));
It yields similar errors for the other 2 times that trim is used.
Here is the "stolen" code:
(Utils.h):
static inline std::string& ltrim(std::string& s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
    return s;
}
// trim from end
static inline std::string& rtrim(std::string& s) {
    s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
    return s;
}
// trim from both ends
static inline std::string& trim(std::string& s) {
    return ltrim(rtrim(s));
}
And here is the parseDVD function that the error mentions:
(DVD.cpp):
DVD DVD::parseDVD(std::string dataStr, std::string delimiter) {
    DVD newDVD;
    int preTitlePos = dataStr.find(delimiter, 0);
    int preGenrePos = dataStr.find(delimiter, preTitlePos + 1);
    // V Error is here V
    std::string rID = trim(dataStr.substr(0, preTitlePos - 1));
    std::string rTitle = trim(dataStr.substr(preTitlePos + 1, preGenrePos - preTitlePos - 1));
    std::string rGenre = trim(dataStr.substr(preGenrePos + 1));
    int parsedID = 0;
    //Requirements for a successful parse
    //The ID must be fully numeric, and both of the delimiters must have been found
    if (parseInt(rID, parsedID) && preTitlePos > -1 && preGenrePos > -1) {
        return
            newDVD  .setID(parsedID)
                    .setTitle(rTitle)
                    .setGenre(rGenre);
    }
    return badDVD;
}
If I remove all of the &s from the trim functions, it works, but I'd rather it not make copies constantly.
This baffles me because I know the code is sound; not only is it the accepted answer to the above question, but it works fine in Visual Studio.
 
     
    