我想首先说是的,我来这里之前谷歌已经解决了这个问题,但没有一个答案似乎有用。
我从What's the best way to trim std::string?窃取了下面的代码,因为无论出于何种原因,都没有标准的c ++ trim
函数。使用Visual Studio,它编译得很好,我设法完成了项目的其余部分而没有给我任何错误。
今天早上,我决定尝试手动编译整个项目(使用g++ -std=c++11 *.cpp
),现在突然trim
函数产生以下错误:
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));
对于使用trim
的其他2次,它会产生类似的错误。
以下是“被盗”代码:
(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));
}
以下是错误提到的parseDVD
函数:
(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;
}
如果我从修剪函数中删除了所有&
,它可以正常工作,但我宁愿不经常复制。
这让我感到困惑,因为我知道代码是合理的;它不仅是上述问题的公认答案,而且在Visual Studio中工作正常。
答案 0 :(得分:7)
您的trim()
函数预计会对const
进行非std::string
引用。当你这样调用它时:
std::string rID = trim(dataStr.substr(0, preTitlePos - 1));
您正在使用右值(一个未命名的临时值)调用它。这将具有类型const std::string &
,因此它与trim()
函数不兼容。为了使其工作,您需要首先将其分配给命名变量:
std::string temp = dataStr.substr(0, preTitlePos - 1);
std::string rID = trim(temp);
在旁注中,您似乎混合了两种从trim()
函数返回输出的方法。通常,一个将返回函数的结果(通常按值),或者一个将修改通过引用传递给函数的参数。你的功能同时做到了,这不是典型的。
我会将它们更改为接受输入参数并按值返回结果,或者修改传入的by-reference参数(并将其返回类型更改为void
)。