title: C++ - Invalid initialization of non-const reference of type
body: <p>I'd like to start by saying that yes, I Google'd this problem before coming here, and none of the answers seemed relevant.</p>
  
  <p>I stole the below code from <a href="https://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring">What&#39;s the best way to trim std::string?</a>, because for whatever reason, there is no standard c++ <code>trim</code> function. Using Visual Studio, it compiled fine, and I managed to complete the rest of the project without it giving me any errors.</p>
  
  <p>This morning though, I decided to try compiling the entire project manually (using <code>g++ -std=c++11 *.cpp</code>), and now suddenly the <code>trim</code> functions are yielding the following error:</p>
  
  <pre><code>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&amp; {aka std::basic_string&lt;char&gt;&amp;}
   from an rvalue of type 'std::basic_string&lt;char&gt;'
   std::string rID = trim(dataStr.substr(0, preTitlePos - 1));
  </code></pre>
  
  <p>It yields similar errors for the other 2 times that <code>trim</code> is used.</p>
  
  <p>Here is the "stolen" code:</p>
  
  <p>(Utils.h):</p>
  
  <pre><code>static inline std::string&amp; ltrim(std::string&amp; s) {
      s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun&lt;int, int&gt;(std::isspace))));
      return s;
  }
  
  // trim from end
  static inline std::string&amp; rtrim(std::string&amp; s) {
      s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun&lt;int, int&gt;(std::isspace))).base(), s.end());
      return s;
  }
  
  // trim from both ends
  static inline std::string&amp; trim(std::string&amp; s) {
      return ltrim(rtrim(s));
  }
  </code></pre>
  
  <p>And here is the <code>parseDVD</code> function that the error mentions:</p>
  
  <p>(DVD.cpp):</p>
  
  <pre><code>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) &amp;&amp; preTitlePos &gt; -1 &amp;&amp; preGenrePos &gt; -1) {
          return
              newDVD  .setID(parsedID)
                      .setTitle(rTitle)
                      .setGenre(rGenre);
      }
  
      return badDVD;
  }
  </code></pre>
  
  <p>If I remove all of the <code>&amp;</code>s from the trim functions, it works, but I'd rather it not make copies constantly.</p>
  
  <p>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.</p>