Boost logo

Boost :

From: Daryle Walker (darylew_at_[hidden])
Date: 2001-05-22 17:24:39


on 5/21/01 10:19 PM, Hubert HOLIN at Hubert.Holin_at_[hidden] wrote:

> Paris (U.E.), le 21/05/2001
[SNIP]
>> 3. The I/O functions had a bunch of errors. The problem was your headers.
>> The <iosfwd> header is OK if you only need the name of an item, like for a
>> pointer or a declaration. If you need an item for a definition, like the
>> implementation of your I/O operators, you need the item's full declaration.
>> I commented out the <iosfwd> #include and added #includes for <istream>,
>> <ostream>, and <sstream> in "quaternion.hpp".

> You mentionned that kind of problem before the review period, but
> I can't find out why you are experiencing them. Could you please detail
> an example of how this occurs, so that I may try to reproduce it.

These are the errors I get (don't trust the line numbers, I've done scratch
work on the file):

//=========================================================================
Error : illegal use of incomplete struct/union/class
'std::basic_ostringstream<char, std::char_traits<char>,
std::allocator<char>>'
 (instantiating:
'boost::__ls<d,c,Q23std14char_traits<c>>(std::basic_ostream<char,
std::char_traits<char>> &, const boost::quaternion<double> &)')
quaternion.hpp line 2868 ::std::basic_ostringstream<charT,traits> s;

Error : illegal use of incomplete struct/union/class
'std::basic_ostringstream<char, std::char_traits<char>,
std::allocator<char>>'
 (instantiating:
'boost::__ls<d,c,Q23std14char_traits<c>>(std::basic_ostream<char,
std::char_traits<char>> &, const boost::quaternion<double> &)')
quaternion.hpp line 2871 s.imbue(os.getloc());

Error : illegal use of incomplete struct/union/class
'std::basic_ostringstream<char, std::char_traits<char>,
std::allocator<char>>'
 (instantiating:
'boost::__ls<d,c,Q23std14char_traits<c>>(std::basic_ostream<char,
std::char_traits<char>> &, const boost::quaternion<double> &)')
quaternion.hpp line 2872 s.precision(os.precision());

Error : illegal operand
 (instantiating:
'boost::__ls<d,c,Q23std14char_traits<c>>(std::basic_ostream<char,
std::char_traits<char>> &, const boost::quaternion<double> &)')
quaternion.hpp line 2874 s << '(' << q.R_component_1() << ','

Error : illegal use of incomplete struct/union/class
'std::basic_ostringstream<char, std::char_traits<char>,
std::allocator<char>>'
 (instantiating:
'boost::__ls<d,c,Q23std14char_traits<c>>(std::basic_ostream<char,
std::char_traits<char>> &, const boost::quaternion<double> &)')
quaternion.hpp line 2879 return os << s.str();

Error : illegal use of incomplete struct/union/class
'std::basic_ostringstream<char, std::char_traits<char>,
std::allocator<char>>'
 (instantiating:
'boost::__ls<f,c,Q23std14char_traits<c>>(std::basic_ostream<char,
std::char_traits<char>> &, const boost::quaternion<float> &)')
quaternion.hpp line 2868 ::std::basic_ostringstream<charT,traits> s;

Error : illegal use of incomplete struct/union/class
'std::basic_ostringstream<char, std::char_traits<char>,
std::allocator<char>>'
 (instantiating:
'boost::__ls<f,c,Q23std14char_traits<c>>(std::basic_ostream<char,
std::char_traits<char>> &, const boost::quaternion<float> &)')
quaternion.hpp line 2871 s.imbue(os.getloc());

Error : illegal use of incomplete struct/union/class
'std::basic_ostringstream<char, std::char_traits<char>,
std::allocator<char>>'
 (instantiating:
'boost::__ls<f,c,Q23std14char_traits<c>>(std::basic_ostream<char,
std::char_traits<char>> &, const boost::quaternion<float> &)')
quaternion.hpp line 2872 s.precision(os.precision());

Error : illegal operand
 (instantiating:
'boost::__ls<f,c,Q23std14char_traits<c>>(std::basic_ostream<char,
std::char_traits<char>> &, const boost::quaternion<float> &)')
quaternion.hpp line 2874 s << '(' << q.R_component_1() << ','

Error : illegal use of incomplete struct/union/class
'std::basic_ostringstream<char, std::char_traits<char>,
std::allocator<char>>'
 (instantiating:
'boost::__ls<f,c,Q23std14char_traits<c>>(std::basic_ostream<char,
std::char_traits<char>> &, const boost::quaternion<float> &)')
quaternion.hpp line 2879 return os << s.str();

//=========================================================================

The reason is given in the error messages, I'm trying to use a class that
only has its name identified, and I need the full definition. The <iosfwd>
header _only_ gives names, it never gives full definitions. So the real
question isn't why my compiler choking, but why yours is letting you get
away with it. My main guess is: between CWP 5.3 and 6.1, a class (template)
in one of the standard headers you #include changed its I/O implementation
to use string-based streams internally. This change necessitated #including
<sstream>, which also #includes <istream> and <ostream>. So you are
"benefiting" from indirect #includes.

Don't depend on indirect #includes, always #include the header for the full
definition (if needed). The reason is that indirect #includes are not
portable. They can be different across compilers (I told someone else here
writing a garbage collector about an indirect <cassert>.) or even versions
of the same compiler (like us here). I think someone here thought that
indirect #includes shouldn't be visible at all! In the future, Metrowerks
could change the implementation again to remove <sstream>, or block indirect
#includes, so why take the risk?

-- 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk