首先我想说是的,我在来这里之前用谷歌搜索了这个问题,但似乎没有一个答案是相关的。
我从 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));
其他 2 次使用 trim
会产生类似的错误。
这是“被盗”的代码:
(实用程序.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;
}
如果我从 trim 函数中删除所有的 &
,它就可以工作,但我宁愿它不要不断地制作拷贝。
这让我感到困惑,因为我知道代码是正确的;它不仅是上述问题的公认答案,而且在 Visual Studio 中也能正常工作。
最佳答案
您的 trim()
函数需要对 std::string
的非const
引用。当你这样调用它时:
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()
函数返回输出的方法。通常,要么返回函数的结果(通常按值),要么修改通过引用传递给函数的参数。您的功能同时执行这两项操作,这并不典型。
我会将它们更改为采用输入参数并按值返回结果,或者修改您传入的按引用参数(并将它们的返回类型更改为 void
)。
关于C++ - 类型的非常量引用的初始化无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29210710/