user11594134
user11594134

Reputation: 129

Error calling both set_rdbuf and rdbuf on std::ifstream

Below is some code I wrote in c++.

ifstream objfile(s1.c_str());

string s2 = strfile; 
std::istringstream objstr(s2);
if (path.empty())  objfile.set_rdbuf(objstr.rdbuf());

It has no problem compile in Visual Studio C++ 2017. When I try to compile using g++ in redhat linux, it has error

error: ‘std::ifstream’ has no member named ‘set_rdbuf’

Edit: Based on the initial answers to this question, I tried replacing the call to set_rdbuf with

objfile.rdbuf(objstr.rdbuf());

This still does not work. It says

rdbuf() const, note: candidate expects 0 arguments, 1 provided.

The full error messages is really long, I removed the lines of In files included from ...

error: no matching function for call to ‘std::basic_ifstream<char>::rdbuf(std::basic_istringstream<char>::__stringbuf_type*)’
   if(path.empty())  objfile.rdbuf(objstr.rdbuf());
                                                 ^
/usr/include/c++/4.8.2/fstream:509:7: note: std::basic_ifstream<_CharT, _Traits>::__filebuf_type* std::basic_ifstream<_CharT, _Traits>::rdbuf() const [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ifstream<_CharT, _Traits>::__filebuf_type = std::basic_filebuf<char>]
       rdbuf() const
       ^

       error: no matching function for call to ‘std::basic_ifstream<char>::rdbuf(std::basic_istringstream<char>::__stringbuf_type*)’
   if (path.empty())  objfile.rdbuf(objstr.rdbuf());
                                                  ^
/usr/include/c++/4.8.2/fstream:509:7: note: std::basic_ifstream<_CharT, _Traits>::__filebuf_type* std::basic_ifstream<_CharT, _Traits>::rdbuf() const [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ifstream<_CharT, _Traits>::__filebuf_type = std::basic_filebuf<char>]
       rdbuf() const
       ^
/usr/include/c++/4.8.2/fstream:509:7: note:   candidate expects 0 arguments, 1 provided

/usr/include/c++/4.8.2/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::basic_istringstream<char>; _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}; _Tp = std::basic_istringstream<char>]’:
/usr/include/c++/4.8.2/bits/alloc_traits.h:254:4:   required from ‘static typename std::enable_if<std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::value, void>::type std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::basic_istringstream<char>; _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}; _Alloc = std::allocator<std::basic_istringstream<char> >; typename std::enable_if<std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::value, void>::type = void]’
/usr/include/c++/4.8.2/bits/alloc_traits.h:393:57:   required from ‘static decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::basic_istringstream<char>; _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}; _Alloc = std::allocator<std::basic_istringstream<char> >; decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) = <type error>]’
/usr/include/c++/4.8.2/bits/vector.tcc:97:40:   required from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}; _Tp = std::basic_istringstream<char>; _Alloc = std::allocator<std::basic_istringstream<char> >]’
/usr/include/c++/4.8.2/bits/stl_vector.h:920:36:   required from ‘void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = std::basic_istringstream<char>; _Alloc = std::allocator<std::basic_istringstream<char> >; std::vector<_Tp, _Alloc>::value_type = std::basic_istringstream<char>]’
/home/research/QZ/6_compile_Agency_Model/Agency_files/BondModel/utility.h:2413:37:   required from here
/usr/include/c++/4.8.2/ext/new_allocator.h:120:4: error: use of deleted function ‘std::basic_istringstream<char>::basic_istringstream(const std::basic_istringstream<char>&)’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^
In file included from /usr/include/c++/4.8.2/complex:45:0,
                 from /home/research/boost_library/boost_1_68_0/boost/detail/container_fwd.hpp:98,
                 from /home/research/boost_library/boost_1_68_0/boost/container_hash/extensions.hpp:22,
                 from /home/research/boost_library/boost_1_68_0/boost/container_hash/hash.hpp:760,
                 from /home/research/boost_library/boost_1_68_0/boost/type_index/stl_type_index.hpp:42,
                 from /home/research/boost_library/boost_1_68_0/boost/type_index.hpp:29,
                 from /home/research/boost_library/boost_1_68_0/boost/any.hpp:20,
                 from /home/research/boost_library/boost_1_68_0/boost/program_options/value_semantic.hpp:12,
                 from /home/research/boost_library/boost_1_68_0/boost/program_options/options_description.hpp:13,

/usr/include/c++/4.8.2/sstream:272:11: note: ‘std::basic_istringstream<char>::basic_istringstream(const std::basic_istringstream<char>&)’ is implicitly deleted because the default definition would be ill-formed:
     class basic_istringstream : public basic_istream<_CharT, _Traits>
           ^
/usr/include/c++/4.8.2/sstream:272:11: error: use of deleted function ‘std::basic_istream<char>::basic_istream(const std::basic_istream<char>&)’


/usr/include/c++/4.8.2/istream:58:11: note: ‘std::basic_istream<char>::basic_istream(const std::basic_istream<char>&)’ is implicitly deleted because the default definition would be ill-formed:
     class basic_istream : virtual public basic_ios<_CharT, _Traits>
           ^
/usr/include/c++/4.8.2/istream:58:11: error: use of deleted function ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’


/usr/include/c++/4.8.2/bits/basic_ios.h:66:11: note: ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’ is implicitly deleted because the default definition would be ill-formed:
     class basic_ios : public ios_base
           ^


/usr/include/c++/4.8.2/bits/ios_base.h:786:5: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
     ios_base(const ios_base&);
     ^

/usr/include/c++/4.8.2/bits/basic_ios.h:66:11: error: within this context
     class basic_ios : public ios_base
           ^

/usr/include/c++/4.8.2/sstream:272:11: error: use of deleted function ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’
     class basic_istringstream : public basic_istream<_CharT, _Traits>
           ^
/usr/include/c++/4.8.2/sstream:272:11: error: use of deleted function ‘std::basic_stringbuf<char>::basic_stringbuf(const std::basic_stringbuf<char>&)’
/usr/include/c++/4.8.2/sstream:64:11: note: ‘std::basic_stringbuf<char>::basic_stringbuf(const std::basic_stringbuf<char>&)’ is implicitly deleted because the default definition would be ill-formed:
     class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
           ^

/usr/include/c++/4.8.2/streambuf:802:7: error: ‘std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]’ is private
       basic_streambuf(const basic_streambuf& __sb)
       ^

/usr/include/c++/4.8.2/sstream:64:11: error: within this context
     class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
           ^
In file included from /usr/include/c++/4.8.2/vector:62:0,

/usr/include/c++/4.8.2/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = std::basic_istringstream<char>; _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}]’:
/usr/include/c++/4.8.2/bits/stl_uninitialized.h:75:53:   required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<std::basic_istringstream<char>*>; _ForwardIterator = std::basic_istringstream<char>*; bool _TrivialValueTypes = false]’
/usr/include/c++/4.8.2/bits/stl_uninitialized.h:117:41:   required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<std::basic_istringstream<char>*>; _ForwardIterator = std::basic_istringstream<char>*]’
/usr/include/c++/4.8.2/bits/stl_uninitialized.h:258:63:   required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<std::basic_istringstream<char>*>; _ForwardIterator = std::basic_istringstream<char>*; _Tp = std::basic_istringstream<char>]’
/usr/include/c++/4.8.2/bits/stl_uninitialized.h:281:69:   required from ‘_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = std::basic_istringstream<char>*; _ForwardIterator = std::basic_istringstream<char>*; _Allocator = std::allocator<std::basic_istringstream<char> >]’
/usr/include/c++/4.8.2/bits/vector.tcc:415:43:   required from ‘void std::vector<_Tp, _Alloc>::_M_emplace_back_aux(_Args&& ...) [with _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}; _Tp = std::basic_istringstream<char>; _Alloc = std::allocator<std::basic_istringstream<char> >]’
/usr/include/c++/4.8.2/bits/vector.tcc:101:54:   required from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}; _Tp = std::basic_istringstream<char>; _Alloc = std::allocator<std::basic_istringstream<char> >]’
/usr/include/c++/4.8.2/bits/stl_vector.h:920:36:   required from ‘void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = std::basic_istringstream<char>; _Alloc = std::allocator<std::basic_istringstream<char> >; std::vector<_Tp, _Alloc>::value_type = std::basic_istringstream<char>]’
/home/research/QZ/6_compile_Agency_Model/Agency_files/BondModel/utility.h:2413:37:   required from here
/usr/include/c++/4.8.2/bits/stl_construct.h:75:7: error: use of deleted function ‘std::basic_istringstream<char>::basic_istringstream(const std::basic_istringstream<char>&)’
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^
make[2]: *** [CMakeFiles/BondModel.dir/cashflowengine.cpp.o] Error 1
make[1]: *** [CMakeFiles/BondModel.dir/all] Error 2

Upvotes: 2

Views: 996

Answers (3)

templatetypedef
templatetypedef

Reputation: 372972

This is quite interesting. As others have noted, the initial issue here is that the set_rdbuf member function is protected, so you can’t call it directly. I was surprised when you reported that calling the correct member function rdbuf didn’t compile, because that member function does exist and is public.

The short version is that I believe the following code will do what you want:

if (path.empty())  objfile.istream::rdbuf(objstr.rdbuf());

The reason you need the istream:: prefix here has to do with how C++ does name lookups in derived classes. If a derived class declares a member function with a given name and you try to call a function with that name, the compiler will not look to base classes to find potential overloads for that function. In C++11, the ifstream type had a new helper function added called rdbuf that returns the underlying buffer as a filebuf*. This shadows the istream function rdbuf that sets the underlying buffer. As a result, if call the one-argument version of rdbuf, C++ won’t find it because it stops searching as soon as it finds the zero-argument rdbuf defined in ifstream. Adding the explicit istream::rdbuf call tells the compiler to search for this function in istream first, where it ends up finding the function you want.

Hope this helps!

Upvotes: 2

Philipp Cla&#223;en
Philipp Cla&#223;en

Reputation: 43999

set_rdbuf is a protected member function. That is why it is not accessible.

Upvotes: 0

Kevin
Kevin

Reputation: 7324

std::ifstream::set_rdbuf is protected, as mentioned here. It's possible that MSVC exposes it as a public member function in std::ifstream which would explain why your code compiles there.

What you want is rdbuf:

std::basic_streambuf<CharT, Traits>* rdbuf( std::basic_streambuf<CharT, Traits>* sb );

Sets the associated stream buffer to sb. The error state is cleared by calling clear(). Returns the associated stream buffer before the operation. If there is no associated stream buffer, returns a null pointer.

Upvotes: 0

Related Questions