使用boost::iostreams::mapped_file_source与宽字符字符串

3
如果我使用窄字符字符串来实例化mapped_file_source(boost 1.46.1),就像下面的示例一样,我不会遇到问题:
boost::iostreams::mapped_file_source m_file_( "testfile.txt" );

然而,如果我尝试使用宽字符串:

boost::iostreams::mapped_file_source m_file_( L"testfile.txt" );

我在VC2010 SP1中遇到了以下编译器错误:

P:\libs\boost_1_46_1\boost/iostreams/device/mapped_file.hpp(128): error C2248: 'boost::iostreams::detail::path::path' : cannot access private member declared in class 'boost::iostreams::detail::path'
          P:\libs\boost_1_46_1\boost/iostreams/detail/path.hpp(111) : see declaration of 'boost::iostreams::detail::path::path'>
          P:\libs\boost_1_46_1\boost/iostreams/detail/path.hpp(37) : see declaration of 'boost::iostreams::detail::path'

如果我尝试传递构造函数一个boost::filesystem::path,则会出现以下错误:

P:\libs\boost_1_46_1\boost/iostreams/device/mapped_file.hpp(128): error C2664: 'boost::iostreams::detail::path::path(const std::string &)' : cannot convert parameter 1 from 'const boost::filesystem3::path' to 'const std::string &'
         Reason: cannot convert from 'const boost::filesystem3::path' to 'const std::string'

我觉得我可能漏掉了一些显而易见的东西,但是我一直在困惑编译器到底在告诉我什么,一直在徒劳地尝试着去理解,但是却越来越迷茫。那种“拍手于额”的时刻似乎永远不会出现... 我到底做错了什么?

在 mapped_file.hpp 中定义的构造函数如下所示:

// Constructor taking a parameters object
template<typename Path>
explicit mapped_file_source(const basic_mapped_file_params<Path>& p);

基本的mapped_file_params类构造函数如下所示:
// Construction from a Path
explicit basic_mapped_file_params(const Path& p) : path(p) { }

// Construction from a path of a different type
template<typename PathT>
explicit basic_mapped_file_params(const PathT& p) : path(p) { }

模板类定义如下:

// This template allows Boost.Filesystem paths to be specified when creating or
// reopening a memory mapped file, without creating a dependence on
// Boost.Filesystem. Possible values of Path include std::string,
// boost::filesystem::path, boost::filesystem::wpath, 
// and boost::iostreams::detail::path (used to store either a std::string or a
// std::wstring).
template<typename Path>
struct basic_mapped_file_params 
    : detail::mapped_file_params_base 
{

在标题中还有一些额外的帮助,它说:
// For wide paths, instantiate basic_mapped_file_params 
// with boost::filesystem::wpath

如果我采取这种方法:

boost::iostreams::basic_mapped_file_params<boost::filesystem::wpath> _tmp(L"test.txt");
boost::iostreams::mapped_file_source m_file_( _tmp );

我遇到了与上述相同的错误。
我知道编译器在告诉我问题所在,但是查看头文件源代码和注释让我相信我尝试实现的内容是支持的,只是我的方法不正确。我是否误解了头文件正在告译我什么?在此之中,可能有关于模板实例化和显式/隐式转换的好课程。
有趣的是,升级我的boost安装到1.47.0似乎清除了C2664错误,但我仍然遇到了关于访问私有成员的C2248错误。
3个回答

2

使用Boost 1.48,我可以这样做。

#include <boost/filesystem.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include <iostream>

int main()
{ 
  boost::filesystem::path p(L"b.cpp");
  boost::iostreams::mapped_file file(p); // or mapped_file_source
  std::cout << file.data() << std::endl;
}

或者您可以使用mapped_file_params(用于创建新文件)来执行此操作。
boost::filesystem::path p(L"aa");
basic_mapped_file_params<boost::filesystem::path> param; // template param
param.path = p;
param.new_file_size = 1024;

1

看起来mapped_file的文档相当陈旧,不反映头文件或头文件注释中的内容。为了使用宽字符字符串实例化boost::iostreams:mapped_file_source对象,您需要明确传递boost::iostreams::detail::path,如下所示:

boost::iostreams::mapped_file_source m_file_( boost::iostreams::detail::path(boost::filesystem::path(L"testfile.txt")) );

我通过逐步查看错误消息并确定模板类的实例化方式,最终成功编译了这个程序。最后发现 boost::iostreams::detail::path 有一个私有构造函数,需要将 &std::wstring 作为参数传入,这也是代码无法编译的原因。

1
它告诉你,boost::iostreams::mapped_file_source的构造函数不接受wchar_t*,也不接受boost::filesystem::path。它只接受std::string或可转换为std::string的类型。换句话说,你不能在此对象中使用UTF-16路径。

我在问题上添加了一些额外的信息。我理解编译器告诉我的内容,但我无法理解为什么从mapped_file.hpp头文件的源代码中会出现这种情况。 - Scott Dillman
@C.Trauma:如果头文件看起来是这样的,那么文档已经过时了。而且我找到的文档页面是1.47.0版本的。 - Nicol Bolas
滚动到文档页面底部会看到“修订于2008年2月2日”,因此它们很可能已经过时了。 - Scott Dillman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接