以下程序尝试使用第一个字符串和指向第一个字符串中间的指针构造第二个字符串:
#include <string>
int main() {
std::string src = "hello world";
const char* end = &src[5];
std::string dest(src.data(), end);
}
Run Code Online (Sandbox Code Playgroud)
在C++ 14及更早版本中,这可行.但是在C++ 17中,调用失败了:
error: no matching function for call to ‘std::__cxx11::basic_string<char>::basic_string(char*, const char*&)’
std::string dest(src.data(), end);
[... full output omitted ...]
Run Code Online (Sandbox Code Playgroud)
改变了什么让这次失败?
Rya*_*ing 33
构造dest是试图使用以下构造函数(来自cppreference):
template< class InputIt >
basic_string( InputIt first, InputIt last,
const Allocator& alloc = Allocator() );
Run Code Online (Sandbox Code Playgroud)
这就要求first,并last具有完全相同的类型.问题是在C++ 17中,std::string::data当在非const上调用时返回非const指针std::string.这意味着firstis char*的类型和lastis 的类型const char*.由于它们不同,InputIt因此无法推断出模板参数,并且调用失败.
没有办法显式指定构造函数调用的模板参数,但有一个解决方案.std::string::c_str仍然返回一个const char*并且dest可以使用它的构造:
std::string dest(src.c_str(), end);
Run Code Online (Sandbox Code Playgroud)
另一个解决方案是呼吁data()在str通过const引用:
const auto& const_src = src;
std::string dest(const_src.data(), end);
Run Code Online (Sandbox Code Playgroud)
或者,如果您不关心C++ 14兼容性,您可以使用std::as_const(感谢MárioFeroldi)
std::string dest(std::as_const(src).data(), end);
Run Code Online (Sandbox Code Playgroud)