首页 / WINDOWS / c – 这是boost :: filesystem中的错误吗?为什么boost :: filesystem :: path :: string()在Windows和Linux上没有相同的签名?
c – 这是boost :: filesystem中的错误吗?为什么boost :: filesystem :: path :: string()在Windows和Linux上没有相同的签名?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c – 这是boost :: filesystem中的错误吗?为什么boost :: filesystem :: path :: string()在Windows和Linux上没有相同的签名?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2305字,纯文字阅读大概需要4分钟。
内容图文
![c – 这是boost :: filesystem中的错误吗?为什么boost :: filesystem :: path :: string()在Windows和Linux上没有相同的签名?](/upload/InfoBanner/zyjiaocheng/970/6f5370ee6c354e688b37a75a53f792b6.jpg)
我正在尝试使用成员函数string()将boost :: filesystem :: path的向量转换为std :: string.我写了这个,它在Windows上工作正常(MSVC 14,2015):
std::transform(
users.begin(), users.end(), std::back_inserter(usersStrs),
std::mem_fn(static_cast<const std::string (PathType::*)() const>(
&PathType::string)));
现在我转到gcc(6.3,Debian Stretch),我的代码给出了上面签名不存在的链接错误.要修复它,我不得不将代码更改为:
std::transform(
users.begin(), users.end(), std::back_inserter(usersStrs),
std::mem_fn(static_cast<const std::string& (PathType::*)() const>(
&PathType::string)))
PS:我知道lambda解决方案更容易,我现在切换到了必需的解决方案.
起初,我认为MSVC更宽容,但后来我切换回Windows并得到相反的链接错误,第一个签名是正确的.我去了源代码(1.64,path.hpp),这是我发现的:
# ifdef BOOST_WINDOWS_API
const std::string string() const
{
std::string tmp;
if (!m_pathname.empty())
path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(),
tmp);
return tmp;
}
//...
# else // BOOST_POSIX_API
// string_type is std::string, so there is no conversion
const std::string& string() const { return m_pathname; }
//...
# endif
所以我看到的原因是在Windows上,因为它默认不使用UTF-8,所以有一个临时转换.但为什么不提升Windows和Linux使用相同的API?最坏的情况是,它会花费一个字符串的副本.对?
我应该使用path :: string()的替代方法来实现跨平台的API稳定性吗?
解决方法:
您可能正在使用旧版本的Boost.Filesystem库. Boost 1.64 says的签名是:
string string(const codecvt_type& cvt=codecvt()) const;
返回类型不依赖于平台;它应该始终是一个值,而不是一个参考.请注意,这(大部分)匹配the C++17 FileSystem library’s definition.因此,如果您在文档说它是一个值时获得引用,那么其中一个是错误的.因此,无论哪种方式都存在错误.
但是,应该注意的是,在C标准中(因此,也可能在Boost中),成员函数的假设是它们不必与文档规范完全匹配.例如,成员函数可以具有标准中未列出的其他默认参数.只要它如所述那样可调用,那就是一个有效的实现.
因此,你不应该期望std :: mem_fn完全像这样工作.使用C标准的措辞,不应该假设path :: string可以转换为具有该签名的成员指针.因此,虽然它可能不一致,但是您可以获得成员指针的期望可能不是Boost支持的接口.
无论是否是错误,您都可以使用lambda轻松解决这个问题:
std::transform(
users.begin(), users.end(), std::back_inserter(usersStrs),
[](const auto &pth) -> decltype(auto) {return pth.string();});
它比std :: mem_fn版本更清晰.如果返回引用,则decltype(auto)会阻止不必要的副本.
内容总结
以上是互联网集市为您收集整理的c – 这是boost :: filesystem中的错误吗?为什么boost :: filesystem :: path :: string()在Windows和Linux上没有相同的签名?全部内容,希望文章能够帮你解决c – 这是boost :: filesystem中的错误吗?为什么boost :: filesystem :: path :: string()在Windows和Linux上没有相同的签名?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。