Чтение из const std::vector<char> через std::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, я искал и до сих пор не нашел способа изменить это. Задание __c1 = __c2 в char_traits У меня еще не было времени даже начать искать способ решения проблемы.

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) Это правило немного расплывчато, но я уверен, что оно четко охватывает ваш случай.

Другие вопросы по тегам