Использование boost :: iostreams :: mapped_file_source с широкими символьными строками - PullRequest
2 голосов
/ 13 июля 2011

Если я создаю экземпляр 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);

Конструкторы класса basic_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 );

Я получаю ту же самую C2664 ошибку, упомянутую выше ..

Я знаю, что компилятор говорит мне, в чем проблема, но, глядя на источник заголовка и комментарии, я верю, что то, что я пытаюсь выполнить, поддерживается, это просто мой подход, который неверен. Я неправильно понимаю, что говорит мне заголовочный файл? Я знаю, что где-то здесь, вероятно, есть хороший урок о создании шаблонов и явном / неявном преобразовании.

Интересно, что обновление моей буст-установки до 1.47.0, похоже, исправило ошибку C2664 , но я все еще получаю ошибку C2248 о доступе к приватному члену.

Ответы [ 3 ]

2 голосов
/ 24 февраля 2012

С бустом 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 голос
/ 14 июля 2011

Похоже, документация для mapped_file довольно старая и не отражает то, что находится в заголовке или в комментариях к заголовку.Для того чтобы создать экземпляр объекта boost::iostreams:mapped_file_source с широкой строкой символов, вам необходимо передать explicity в 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 голос
/ 13 июля 2011

Это говорит вам, что конструктор boost::iostreams::mapped_file_source не принимает wchar_t* и не принимает boost::filesystem::path.Это займет всего std::string или типы, конвертируемые в std::string.Или, другими словами, вы не можете использовать пути UTF-16 с этим объектом.

...