通过std :: istream </char>从const std :: vector <char>读取

时间:2014-08-04 20:14:50

标签: c++11 vector istream

我试图从const std :: vector读取到std :: istream,但我尝试的所有内容都遇到了const问题。

此版本完美编译:

#include <vector>
#include <iostream>

template<typename CharT = char, typename TraitsT = std::char_traits<CharT> >
class vectorbuf : public std::basic_streambuf<CharT, TraitsT> {
public:
    vectorbuf(std::vector<char>& v) {
        this->setg(v.data(), v.data(), v.data()+v.size());
    }
};

void doStuff(std::vector<char>& v) {
    vectorbuf<> vbuff(v);
    std::istream s(&vbuff);
}

int main(int argc, char** argv) {
    std::vector<char> v = {'a', 'b', 'c'};
    doStuff(v);
    return 0;
}

虽然会产生错误:

#include <vector>
#include <iostream>

template<typename CharT = char, typename TraitsT = std::char_traits<CharT> >
class const_vectorbuf : public std::basic_streambuf<CharT, TraitsT> {
public:
    const_vectorbuf(const std::vector<char>& v) {
        this->setg(v.data(), v.data(), v.data()+v.size());
    }
};

void const_doStuff(const std::vector<char>& v) {
    const_vectorbuf<const char> vbuff(v);
    //std::istream s(&vbuff); With this commented out I get the error below
}

int main(int argc, char** argv) {
    std::vector<char> v = {'a', 'b', 'c'};
    const_doStuff(v);
    return 0;
}

我不确定如何修复它。

错误:

In file included from /usr/include/c++/4.8/ios:40:0,
                 from /usr/include/c++/4.8/ostream:38,
                 from /usr/include/c++/4.8/iostream:39,
                 from vector_stream.cpp:2:
/usr/include/c++/4.8/bits/char_traits.h: In instantiation of ‘static void __gnu_cxx::char_traits<_CharT>::assign(__gnu_cxx::char_traits<_CharT>::char_type&, const char_type&) [with _CharT = const char; __gnu_cxx::char_traits<_CharT>::char_type = const char]’:
/usr/include/c++/4.8/bits/streambuf.tcc:67:63:   required from ‘std::streamsize std::basic_streambuf<_CharT, _Traits>::xsgetn(std::basic_streambuf<_CharT, _Traits>::char_type*, std::streamsize) [with _CharT = const char; _Traits = std::char_traits<const char>; std::streamsize = long int; std::basic_streambuf<_CharT, _Traits>::char_type = const char]’
vector_stream.cpp:36:1:   required from here
/usr/include/c++/4.8/bits/char_traits.h:93:14: error: assignment of read-only reference ‘__c1’
       { __c1 = __c2; }
              ^
In file included from /usr/include/c++/4.8/vector:60:0,
                 from vector_stream.cpp:1:
/usr/include/c++/4.8/bits/stl_algobase.h: In instantiation of ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = const char*; _OI = const char*]’:
/usr/include/c++/4.8/bits/stl_algobase.h:428:38:   required from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = const char*; _OI = const char*]’
/usr/include/c++/4.8/bits/stl_algobase.h:460:17:   required from ‘_OI std::copy(_II, _II, _OI) [with _II = const char*; _OI = const char*]’
/usr/include/c++/4.8/bits/char_traits.h:192:39:   required from ‘static __gnu_cxx::char_traits<_CharT>::char_type* __gnu_cxx::char_traits<_CharT>::copy(__gnu_cxx::char_traits<_CharT>::char_type*, const char_type*, std::size_t) [with _CharT = const char; __gnu_cxx::char_traits<_CharT>::char_type = const char; std::size_t = long unsigned int]’
/usr/include/c++/4.8/bits/streambuf.tcc:56:50:   required from ‘std::streamsize std::basic_streambuf<_CharT, _Traits>::xsgetn(std::basic_streambuf<_CharT, _Traits>::char_type*, std::streamsize) [with _CharT = const char; _Traits = std::char_traits<const char>; std::streamsize = long int; std::basic_streambuf<_CharT, _Traits>::char_type = const char]’
vector_stream.cpp:36:1:   required from here
/usr/include/c++/4.8/bits/stl_algobase.h:390:70: error: no matching function for call to ‘std::__copy_move<false, true, std::random_access_iterator_tag>::__copy_m(const char*&, const char*&, const char*&)’
                        _Category>::__copy_m(__first, __last, __result);
                                                                      ^
/usr/include/c++/4.8/bits/stl_algobase.h:390:70: note: candidate is:
/usr/include/c++/4.8/bits/stl_algobase.h:368:9: note: template<class _Tp> static _Tp* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(const _Tp*, const _Tp*, _Tp*) [with _Tp = _Tp; bool _IsMove = false]
         __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result)
         ^
/usr/include/c++/4.8/bits/stl_algobase.h:368:9: note:   template argument deduction/substitution failed:
/usr/include/c++/4.8/bits/stl_algobase.h:390:70: note:   deduced conflicting types for parameter ‘_Tp’ (‘char’ and ‘const char’)
                        _Category>::__copy_m(__first, __last, __result);

所以尽管CharT是const char,但streambuf_type仍然是char,我一直在寻找,到目前为止我还没有找到改变它的方法。 char_traits中的作业__c1 = __c2我还没有时间开始寻找解决方法。

1 个答案:

答案 0 :(得分:1)

我确信basic_streambuf要求第一个模板不是 - const。另外,我认为basic_streambuf需要写入权限,因为basic_streambuf管理进出,无论你最终使用它是什么。您可能还应该覆盖其他一些成员以导致写入失败:sputbackc, sungetc, sputc, sputn, xsputn ...

  

§27.2.2/ 2在第27条的类中,名为charT的模板形式参数表示包含char,wchar_t和的任何其他实现定义的字符类型的类型集合的成员。可以实例化任何iostream组件的字符的要求

(emphsis mine)这个规则有点模糊,但我很确定它清楚地涵盖了你的情况。