[英]Strange exception from boost::lexical_cast with boost::filesystem
在RHEL7.4上,提升1.53,
#include <iostream>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost;
int main() {
const string& s1 = "1024";
cout << "test1:" << lexical_cast<unsigned int>(s1) << endl;
filesystem::path p("1024");
cout << "test2:" << lexical_cast<unsigned int>(p.filename().string()) << endl;
const string& s2 = p.filename().string();
cout << "test3:" << lexical_cast<unsigned int>(s2) << endl;
return 0;
}
此代码给出:
test1:1024
test2:1024
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_lexical_cast> >'
what(): bad lexical cast: source type value could not be interpreted as target
zsh: abort ./a.out
也许这是一个lexical_cast的bug,但有人知道为什么test3会失败? 特别是,我无法理解test1和3之间的不同。
这一行创建了一个悬空参考:
const string& s2 = p.filename().string();
那是因为在POSIX系统上, path::filename()
返回对成员的引用 (!!!)。 因此,不会发生生命周期延长,就像它已经返回一个临时的一样。
现在,因为filename()
返回一个临时path()
,引用不再有效。 您的程序调用未定义的行为。
我建议修复如下:
p = p.filename();
const string& s2 = p.string();
cout << "test3:" << lexical_cast<unsigned int>(s2) << endl;
要么
p = p.filename();
cout << "test3:" << lexical_cast<unsigned int>(p.string()) << endl;
甚至
cout << "test3:" << lexical_cast<unsigned int>(p.filename().string()) << endl;
最重要的是保持简单:
std::string const s2 = p.filename().string();
cout << "test3:" << lexical_cast<unsigned int>(s2) << endl;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.