pf.string()
输出似乎有一些奇怪的行为,其中 pf
是用 p.filename()
生成的,其中 p
是 boost::filesystem::path
类型,由 char const* 或 std::string 构造。
这是代码段:
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
int main(int argc, char **argv) {
fs::path p(argv[0]); // or fs::path p((std::string(argv[0])));
fs::path &&pf = p.filename(); // or fs::path pf = p.filename();
std::string const &name = p.filename().string();
std::cout << "*" << name << "*\n";
std::string const &p_name = pf.string();
std::cout << "*" << p_name << "*\t";
std::cout << "*" << name << "*\n";
std::string s_name = p.filename().string();
std::cout << "*" << s_name << "*\t";
std::cout << "*" << name << "*\n";
return 0;
}
这里的argv[0]
是fs.out
和可执行文件的输出(用clang3.4
编译/ gcc4.9
与 -O3
/-O0
) 是:
**
*fs.out* **
*fs.out* *fs.out*
我使用的 boost 版本是 1.55 来自 Debian jessie(testing) 包。
我的问题:
- 为什么
name
的前两行是空的? - 为什么
p_name
不为空而name
在第 2 行为空? - 为什么这个程序在第 3 行有正确的(?)输出,尽管
s_name
和name
之间似乎没有关系?
最佳答案
您正在引用临时对象。
如果绑定(bind)到 const
引用(如 p_name
),临时对象的生命周期将延长到包含范围的末尾。
否则,您只是在调用未定义的行为。这也解释了当您分配给一个完全不同的变量时 name
是如何变化的。这显然是因为 s_name
碰巧 分配了 name
仍然(错误地!)引用的相同内存块。可能会发生更糟糕的事情。
您应该按值获取 filename()
(和 friend )的返回值(如果类型支持的话,在现代编译器上应该自动表现为 move) .
注意 MSVC 确实“似乎”接受此代码并“做你期望的事”——大概是因为它有一个非标准的扩展,即使在绑定(bind)时也允许延长临时对象的生命周期到非常量引用。
关于c++ - boost::filesystem::path::string() 输出的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25788116/