boost :: lexical_cast与boost :: filesystem的奇怪异常

时间:2018-03-07 02:37:16

标签: c++ boost

在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的错误,但有人知道为什么test3会失败?特别是,我无法理解test1和3之间的不同。

1 个答案:

答案 0 :(得分:2)

此行创建悬空参考:

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;