file_descripterのコンストラクタ

いろいろ問題の尽きないboost::iostreams::file_descriptorですが、コンストラクタに危険な罠が潜んでいます。

#include <boost/iostreams/device/file_descriptor.hpp>

namespace io = boost::iostreams;

int main()
{
    io::file_descriptor file("hoge.txt");

    // fileを使った処理
    ...
}

この一見なんでもないコードが、Windowsでは動きません。

namespace boost { namespace iostreams {

class BOOST_IOSTREAMS_DECL file_descriptor {
public:
#ifdef BOOST_IOSTREAMS_WINDOWS
    typedef void*  handle_type;
#endif
    typedef char   char_type;
    struct category
        : seekable_device_tag,
          closable_tag
        { };
    file_descriptor() : pimpl_(new impl) { }
    explicit file_descriptor(int fd, bool close_on_exit = false)
        : pimpl_(new impl(fd, close_on_exit))
        { }
#ifdef BOOST_IOSTREAMS_WINDOWS
    explicit file_descriptor(handle_type handle, bool close_on_exit = false)
        : pimpl_(new impl(handle, close_on_exit))
        { }
#endif
    explicit file_descriptor( const std::string& path,
                              BOOST_IOS::openmode mode =
                                  BOOST_IOS::in | BOOST_IOS::out,
                              BOOST_IOS::openmode base_mode =
                                  BOOST_IOS::in | BOOST_IOS::out )
        : pimpl_(new impl)
    { open(path, mode, base_mode); }

BOOST_IOSTREAMS_WINDOWSが定義されている場合、上記のコードはfile_descriptor(const std::string&,BOOST_IOS::openmode,BOOST_IOS::openmode)ではなく、file_descriptor(handle_type,bool)の方が呼ばれてしまいます。
というわけで以下のように書く必要があります。

#include <boost/iostreams/device/file_descriptor.hpp>

namespace io = boost::iostreams;

int main()
{
    io::file_descriptor file(std::string("hoge.txt"));

    // fileを使った処理
    ...
}