Reputation: 129
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
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
Reputation: 43999
set_rdbuf is a protected member function. That is why it is not accessible.
Upvotes: 0
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