这是OpenGL Super Bible第7版的片段:
GLint log_length;
glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &log_length);
std::string str;
str.reserve(log_length);
glGetShaderInfoLog(fs, log_length, NULL, str.c_str());
Run Code Online (Sandbox Code Playgroud)
乍一看,str.c_str()作为一个论证来传达这个功能对我来说似乎很奇怪,当然clang立即抗议:cannot initialize a parameter of type 'GLchar *' (aka 'char *') with an rvalue of type 'const char *'.
所以我尝试调查并更改str.c_str()为str.data(),它应该提供指向内部数据数组的指针,但这会产生相同的错误消息.编辑: c_str()并且data()实际上是相同的东西(至少在c ++ 11中),所以我们使用哪一个并不重要.
我做了一些搜索,但没有找到解决方案(虽然我对C++很新,有些事情对我来说仍然不明显).
这是书中的错误吗?有没有办法让它与std :: string一起使用?
双方string::c_str()并string::data()返回const char*到C++ 17.从C++ 17开始,string::data()有一个重载会返回一个char*.这意味着此代码段无效.
编辑:使用更简单,更有效的解决方案&str[0].下标运算符将返回a char&.
如果你不能使用C++ 17,你可以使用a std::vector<char>,它有一个非const data(),但这会在构造一个时产生一个副本std::string:
// ...
std::vector<char> v(log_length);
glGetShaderInfoLog(fs, log_length, NULL, v.data());
std::string s(begin(v), end(v));
Run Code Online (Sandbox Code Playgroud)
另外,reserve()还不够,因为实际size()没有改变.如果c_str()返回a char*,则片段实际上也会导致未定义的行为.