Bug 8567 - std::endl is of unknown type when overloading operator<< (repeat in case attachment didnt work)
Summary: std::endl is of unknown type when overloading operator<< (repeat in case atta...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 8566 (view as bug list)
Depends on:
Blocks:
 
Reported: 2002-11-13 13:36 UTC by jstanek
Modified: 2003-07-25 17:33 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Unknown.cpp (217 bytes, application/octet-stream)
2003-05-21 15:16 UTC, jstanek
Details

Note You need to log in before you can comment on or make changes to this bug.
Description jstanek 2002-11-13 13:36:01 UTC
cruncher 109% g++32 -v -save-temps Unknown.cpp 
Reading specs from /home/users/jstanek/gcc-3.2/irix/lib/gcc-lib/mips-sgi-irix6.5/3.2/specs
Configured with: ../gcc-3.2-src/configure --prefix=/home/users/jstanek/gcc-3.2 --exec-prefix=/home/users/jstanek/gcc-3.2/irix
Thread model: single
gcc version 3.2
 /home/users/jstanek/gcc-3.2/irix/lib/gcc-lib/mips-sgi-irix6.5/3.2/cpp0 -lang-c++ -D__GNUG__=3 -D__DEPRECATED -D__EXCEPTIONS -v -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=0 -D__GXX_ABI_VERSION=102 -Dunix -Dmips -Dsgi -Dhost_mips -DMIPSEB -D_MIPSEB -DSYSTYPE_SVR4 -D_LONGLONG -D_SVR4_SOURCE -D_MODERN_C -D__DSO__ -D__unix__ -D__mips__ -D__sgi__ -D__host_mips__ -D__MIPSEB__ -D_MIPSEB -D__SYSTYPE_SVR4__ -D_LONGLONG -D_SVR4_SOURCE -D_MODERN_C -D__DSO__ -D__unix -D__mips -D__sgi -D__host_mips -D__MIPSEB -D__SYSTYPE_SVR4 -Asystem=unix -Asystem=svr4 -Acpu=mips -Amachine=sgi -D__NO_INLINE__ -D__STDC_HOSTED__=1 -D__LANGUAGE_C_PLUS_PLUS -D_LANGUAGE_C_PLUS_PLUS -D__SIZE_TYPE__=unsigned int -D__PTRDIFF_TYPE__=int -D__WCHAR_TYPE__=long int -D__WINT_TYPE__=long int -D__mips_fpr=64 -D__EXTENSIONS__ -D_SGI_SOURCE -D_MIPS_FPSET=32 -D_MIPS_ISA=_MIPS_ISA_MIPS3 -D_ABIN32=2 -D_MIPS_SIM=_ABIN32 -D_MIPS_SZINT=32 -D_MIPS_SZLONG=32 -D_MIPS_SZPTR=32 -D_COMPILER_VERSION=601 -U__mips -D__mips=3 -D__mips64 Unknown.cpp Unknown.ii
GNU CPP version 3.2 (cpplib) [AL 1.1, MM 40] SGI running IRIX 6.x
ignoring nonexistent directory "/home/users/jstanek/gcc-3.2/irix/mips-sgi-irix6.5/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/users/jstanek/gcc-3.2/include/c++/3.2
 /home/users/jstanek/gcc-3.2/include/c++/3.2/mips-sgi-irix6.5
 /home/users/jstanek/gcc-3.2/include/c++/3.2/backward
 /usr/local/include
 /home/users/jstanek/gcc-3.2/include
 /home/users/jstanek/gcc-3.2/irix/lib/gcc-lib/mips-sgi-irix6.5/3.2/include
 /usr/include
End of search list.
 /home/users/jstanek/gcc-3.2/irix/lib/gcc-lib/mips-sgi-irix6.5/3.2/cc1plus -fpreprocessed Unknown.ii -quiet -dumpbase Unknown.cpp -version -o Unknown.s
GNU CPP version 3.2 (cpplib) [AL 1.1, MM 40] SGI running IRIX 6.x
GNU C++ version 3.2 (mips-sgi-irix6.5)
	compiled by GNU C version 3.2.
Unknown.cpp: In function `int main()':
Unknown.cpp:25: no match for `BlackHole& << <unknown type>' operator


When overloading the operator<< for a class other than of type ostream, the compiler is unable to find the type of std::endl.

The compiler should be able to find the type of std::endl, since it should be a function pointer.  This happens on irix g++3.2, irix g++3.0.4, linux g++3.2, and linux g++3.0.4 (probably all 3.0+ compilers).


Since I'm not sure the attachment was received correctly, I apologize, but I am sending the bug report again with the file text included here:

//////////////////////////////////////////////////////
#include <iostream>

//#define endl endl<char,std::char_traits<char> >

class BlackHole{};

template <typename T>
BlackHole& operator<<(BlackHole& bh, const T& dummy)
{
  return bh;
}

template <typename T>
BlackHole& operator<<(BlackHole& bh, T& (*dummy)(T&))
{
  return bh;
}

int main()
{
  BlackHole bh;

  std::cout << "hi" << std::endl;
  std::endl(std::cout);

  bh << std::endl;  
  
  return 0;
}


//////////////////////////////////////////////////////

Release:
gcc-3.2

Environment:
cruncher 110% uname -a
IRIX64 cruncher 6.5 07121149 IP27

cruncher 109% g++32 -v -save-temps Unknown.cpp 
Reading specs from /home/users/jstanek/gcc-3.2/irix/lib/gcc-lib/mips-sgi-irix6.5/3.2/specs
Configured with: ../gcc-3.2-src/configure --prefix=/home/users/jstanek/gcc-3.2 --exec-prefix=/home/users/jstanek/gcc-3.2/irix
Thread model: single
gcc version 3.2
 /home/users/jstanek/gcc-3.2/irix/lib/gcc-lib/mips-sgi-irix6.5/3.2/cpp0 -lang-c++ -D__GNUG__=3 -D__DEPRECATED -D__EXCEPTIONS -v -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=0 -D__GXX_ABI_VERSION=102 -Dunix -Dmips -Dsgi -Dhost_mips -DMIPSEB -D_MIPSEB -DSYSTYPE_SVR4 -D_LONGLONG -D_SVR4_SOURCE -D_MODERN_C -D__DSO__ -D__unix__ -D__mips__ -D__sgi__ -D__host_mips__ -D__MIPSEB__ -D_MIPSEB -D__SYSTYPE_SVR4__ -D_LONGLONG -D_SVR4_SOURCE -D_MODERN_C -D__DSO__ -D__unix -D__mips -D__sgi -D__host_mips -D__MIPSEB -D__SYSTYPE_SVR4 -Asystem=unix -Asystem=svr4 -Acpu=mips -Amachine=sgi -D__NO_INLINE__ -D__STDC_HOSTED__=1 -D__LANGUAGE_C_PLUS_PLUS -D_LANGUAGE_C_PLUS_PLUS -D__SIZE_TYPE__=unsigned int -D__PTRDIFF_TYPE__=int -D__WCHAR_TYPE__=long int -D__WINT_TYPE__=long int -D__mips_fpr=64 -D__EXTENSIONS__ -D_SGI_SOURCE -D_MIPS_FPSET=32 -D_MIPS_ISA=_MIPS_ISA_MIPS3 -D_ABIN32=2 -D_MIPS_SIM=_ABIN32 -D_MIPS_SZINT=32 -D_MIPS_SZLONG=32 -D_MIPS_SZPTR=32 -D_COMPILER_VERSION=601 -U__mips -D__mips=3 -D__mips64 Unknown.cpp Unknown.ii
GNU CPP version 3.2 (cpplib) [AL 1.1, MM 40] SGI running IRIX 6.x
ignoring nonexistent directory "/home/users/jstanek/gcc-3.2/irix/mips-sgi-irix6.5/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/users/jstanek/gcc-3.2/include/c++/3.2
 /home/users/jstanek/gcc-3.2/include/c++/3.2/mips-sgi-irix6.5
 /home/users/jstanek/gcc-3.2/include/c++/3.2/backward
 /usr/local/include
 /home/users/jstanek/gcc-3.2/include
 /home/users/jstanek/gcc-3.2/irix/lib/gcc-lib/mips-sgi-irix6.5/3.2/include
 /usr/include
End of search list.
 /home/users/jstanek/gcc-3.2/irix/lib/gcc-lib/mips-sgi-irix6.5/3.2/cc1plus -fpreprocessed Unknown.ii -quiet -dumpbase Unknown.cpp -version -o Unknown.s
GNU CPP version 3.2 (cpplib) [AL 1.1, MM 40] SGI running IRIX 6.x
GNU C++ version 3.2 (mips-sgi-irix6.5)
	compiled by GNU C version 3.2.
Unknown.cpp: In function `int main()':
Unknown.cpp:25: no match for `BlackHole& << <unknown type>' operator

How-To-Repeat:
Compile the file using g++.
Comment 1 jstanek 2002-11-13 13:36:01 UTC
Fix:
instead of using std::endl, use std::endl<char,char_traits<char> > or 
#define endl endl<char,std::char_traits<char> >

Should I really have to do this?  This seems really wordy and a waste of time.  I would really appreciate it if someone let me know a better way to do this.

Thanks,
-Jason
Comment 2 Wolfgang Bangerth 2002-11-14 15:37:17 UTC
State-Changed-From-To: open->closed
State-Changed-Why: Not a bug. Basically, it is this:
    ---------------------------------
    namespace std {
      template <typename T> T& endl (T&);
    };
    
    class BlackHole{};
    
    template <typename T> BlackHole& operator<<(BlackHole& bh, const T& dummy);
    template <typename T> BlackHole& operator<<(BlackHole& bh, T& (*dummy)(T&));
    
    int main() {
      BlackHole bh;
      bh << std::endl;  
    }
    -------------------------------
    Since there is no unambiguous function std::endl, the
    compiler cannot know which one to take as argument, so
    you have to disambiguate the situation by passing it the
    exact template argument list. Alternatively, you can give
    an overloaded non-template op<<; in this example, this 
    would do:
      BlackHole& operator<<(BlackHole& bh, int& (*dummy)(int&));
    Then std::endl<int> would be taken.
    
    W.
Comment 3 jstanek 2002-11-14 21:13:20 UTC
From: Jason Stanek <jstanek@iastate.edu>
To: bangerth@dealii.org, gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org,
        jstanek@iastate.edu, jstanek@vrac.iastate.edu, nobody@gcc.gnu.org,
        gcc-gnats@gcc.gnu.org
Cc:  
Subject: Re: c++/8567: std::endl is of unknown type when overloading
  operator<< (repeat in case attachment didnt work)
Date: Thu, 14 Nov 2002 21:13:20 -0600

 Isnt there a way to specify a default template type?
 
 So instead of declaring endl as a pure template, it has a default type in 
 the case that you dont specify one.
 
 Something like this:
 
 namespace std {
        template <typename T=int> T& endl (T&);
 };
 
 -Jason
 
 At 11:37 PM 11/14/2002 +0000, you wrote:
 >Synopsis: std::endl is of unknown type when overloading operator<< (repeat 
 >in case attachment didnt work)
 >
 >State-Changed-From-To: open->closed
 >State-Changed-By: bangerth
 >State-Changed-When: Thu Nov 14 15:37:17 2002
 >State-Changed-Why:
 >     Not a bug. Basically, it is this:
 >     ---------------------------------
 >     namespace std {
 >       template <typename T> T& endl (T&);
 >     };
 >
 >     class BlackHole{};
 >
 >     template <typename T> BlackHole& operator<<(BlackHole& bh, const T& 
 > dummy);
 >     template <typename T> BlackHole& operator<<(BlackHole& bh, T& 
 > (*dummy)(T&));
 >
 >     int main() {
 >       BlackHole bh;
 >       bh << std::endl;
 >     }
 >     -------------------------------
 >     Since there is no unambiguous function std::endl, the
 >     compiler cannot know which one to take as argument, so
 >     you have to disambiguate the situation by passing it the
 >     exact template argument list. Alternatively, you can give
 >     an overloaded non-template op<<; in this example, this
 >     would do:
 >       BlackHole& operator<<(BlackHole& bh, int& (*dummy)(int&));
 >     Then std::endl<int> would be taken.
 >
 >     W.
 >
 >http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=8567
 
 
 

Comment 4 Wolfgang Bangerth 2002-11-15 10:06:47 UTC
From: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
To: Jason Stanek <jstanek@iastate.edu>
Cc: gcc-bugs@gcc.gnu.org, <jstanek@vrac.iastate.edu>, <gcc-gnats@gcc.gnu.org>
Subject: Re: c++/8567: std::endl is of unknown type when overloading  operator<<
 (repeat in case attachment didnt work)
Date: Fri, 15 Nov 2002 10:06:47 -0600 (CST)

 > Isnt there a way to specify a default template type?
 > 
 > So instead of declaring endl as a pure template, it has a default type in 
 > the case that you dont specify one.
 > 
 > Something like this:
 > 
 > namespace std {
 >        template <typename T=int> T& endl (T&);
 > };
 
 Default template arguments are only possible for classes, not for function 
 templates.
 
 Regards
   Wolfgang
 
 -------------------------------------------------------------------------
 Wolfgang Bangerth              email:           bangerth@ticam.utexas.edu
                                www: http://www.ticam.utexas.edu/~bangerth
 
 

Comment 5 brondsem 2003-05-10 10:36:08 UTC
From: Dave Brondsema <brondsem@yahoo.com>
To: gcc-gnats@gcc.gnu.org, jstanek@vrac.iastate.edu, gcc-bugs@gcc.gnu.org,
  nobody@gcc.gnu.org, gcc-prs@gcc.gnu.org, jstanek@iastate.edu
Cc:  
Subject: Re: c++/8567: std::endl is of unknown type when overloading operator<< (repeat in case attachment didnt work)
Date: Sat, 10 May 2003 10:36:08 -0700 (PDT)

 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=8567
 
 The following 2 samples are based on the solutions given, but
 still fail to compile.  I'm using g++ (GCC) 3.2.2 on i686
 
 #include <iostream>
 
 class BlackHole{};
 
 template <typename T> BlackHole& operator<<(BlackHole& bh, const
 T& dummy);
 template <typename T> BlackHole& operator<<(BlackHole& bh, T&
 (*dummy)(T&));
 
 int main() {
     BlackHole bh;
     bh << std::endl;
 }
 
 =======
 test.cpp: In function `int main()':
 test.cpp:11: no match for `BlackHole& << <unknown type>'
 operator
 
 =======
 =======
 #include <iostream>
 
 class BlackHole{};
 
 template <typename T> BlackHole& operator<<(BlackHole& bh, const
 T& dummy);
 (*dummy)(T&));
 BlackHole& operator<<(BlackHole& bh, int& (*dummy)(int&));
 
 int main() {
     BlackHole bh;
     bh << std::endl;
 }
 
 =======
 test.cpp: In function `int main()':
 test.cpp:11: no match for `BlackHole& << <unknown type>'
 operator
 test.cpp:7: candidates are: BlackHole& operator<<(BlackHole&,
 int&(*)(int&))
 
 
 
 
 =====
 Dave Brondsema
 dave@brondsema.net
 http://www.brondsema.net - personal
 http://www.splike.com - programming
 
 __________________________________
 Do you Yahoo!?
 The New Yahoo! Search - Faster. Easier. Bingo.
 http://search.yahoo.com
Comment 6 Dave Brondsema 2003-05-28 17:34:11 UTC
The proper syntax for handling endl (and other related iostream things) is
described here:
http://groups.google.com/groups?threadm=3e2dd467%240%248536%24724ebb72%40reader2.ash.ops.us.uu.net

I do not understand it fully, but this works:

BlackHole& operator<<(BlackHole& bh, ostream&(*f)(ostream&));

And then to make use of the 'f' parameter, assuming you had my_stream as some
sort of private stream, you could do f(my_stream);