通过函数打开流 [英] Opening stream via function

查看:304
本文介绍了通过函数打开流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要帮助 [io](f)流的不可复制性质。

I need help with the non-copyable nature of [io](f)streams.

我需要为 fstream 提供一个hackish包装,以便处理在Windows上的文件名中带有unicode字符的文件。为此,我设计了一个包装器函数:

I need to provide a hackish wrapper around fstreams in order to handle files with unicode characters in their filenames on Windows. For this, I devised a wrapper function:

bool open_ifstream( istream &stream, const string &filename )
{
#ifdef __GLIBCXX__
    FILE* result = _wfopen( convert_to_utf16(filename).c_str(), L"r" );
    if( result == 0 )
        return false;

    __gnu_cxx::stdio_filebuf<char>* buffer = new __gnu_cxx::stdio_filebuf<char>( result, std::ios_base::in, 1 );
    istream stream2(buffer);
    std::swap(stream, stream2);

#elif defined(_MSC_VER)
    stream.open( convert_to_utf16(filename) );
#endif
    return !!stream;
}

当然, std :: swap 行是罪魁祸首。我也尝试从函数返回流,但它导致相同的问题。 std :: istream 的复制构造函数为 delete d。我也尝试了一个 std :: move 但是没有帮助。如何解决此问题?

With of course the std::swap line being the culprit. I also tried returning the stream from the function, but it leads to the same problem. The copy constructor of a std::istream is deleted. I also tried a std::move but that didn't help. How do I work around this problem?

编辑:我终于找到了一个好办法 Keep It Simple ),但功能齐全,感谢@ tibur的想法。它仍然是hackish的意义上,它取决于使用的Windows标准C ++库,但由于只有两个实际的在使用,这对我来说不是一个问题。

I finally found a good way to Keep It Simple (TM) and yet functional, thanks to @tibur's idea. It's still hackish in the sense that it depends on the Windows Standard C++ library used, but as there's only two real ones in use, it's not really a problem for me.

#include <fstream>
#include <memory>
#if _WIN32
# if __GLIBCXX__
#  include<ext/stdio_filebuf.h>
unique_ptr<istream> open_ifstream( const string &filename )
{
    FILE* c_file = _wfopen( convert_to_utf16(filename).c_str(), L"r" );
    __gnu_cxx::stdio_filebuf<char>* buffer = new __gnu_cxx::stdio_filebuf<char>( c_file, std::ios_base::in, 1 );

    return std::unique_ptr<istream>( new istream(buffer) );
}
# elif _MSC_VER
unique_ptr<ifstream> open_ifstream( const string &filename )
{
    return unique_ptr<ifstream>(new ifstream( convert_to_utf16(filename)) );
}
# else
# error unknown fstream implementation
# endif
#else
unique_ptr<ifstream> open_ifstream( const string &filename )
{
    return unique_ptr<ifstream>(new ifstream(filename) );
}
#endif

而在用户代码中:

auto stream_ptr( open_ifstream(filename) );
auto &stream = *stream_ptr;
if( !stream )
    return emit_error( "Unable to open nectar file: " + filename );

这取决于C ++ 0x < memory> auto 关键字。当然你不能只是关闭产生的变量,而是GNU Libstdc ++ std :: istream 析构函数负责关闭文件,因此在任何地方不需要额外的内存管理。

Which depends on C++0x <memory> and the auto keyword. Of course you can't just close the resulting stream variable, but the GNU Libstdc++ std::istream destructor does take care of closing the file, so no extra memory management is required anywhere.

推荐答案

关于:

ifstream * open_ifstream(const string &filename);

这篇关于通过函数打开流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆