🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #2199

Re: STL <iostream> vs. <iostream.h>

#2199
From: Jason Merrill
Date: Fri, 13 Oct 1995 18:00
143 lines
7247 bytes
>>>>> Jirtme Desquilbet <jDesquilbet@Rational.COM> writes:

>   #include <iostream>
>   using std::cout;
>   using std::endl;

>   int main()
>   {
>     cout << "Hello, world!" << endl;
>   }

> And what about <<?
> Is not something like:

>   using std::operator<<;

> necessary?

Nope; << is looked up in the context of ostream, which is namespace std, so
the definition there is found.  This is known as 'Koenig lookup'.

  13.3.1.2  Operators in expressions                   [over.match.oper]

1 If  no  operand  of  an operator in an expression has a type that is a
  class or an enumeration, the operator is  assumed  to  be  a  built-in
  operator  and  interpreted according to clause _expr_.  [Note: because
  ., .*, ::, and ?: cannot be overloaded,  these  operators  are  always
  built-in  operators  interpreted according to clause _expr_.  ] [Exam-
  ple:
          class String {
          public:
             String (const String&);
             String (char*);
                  operator char* ();
          };
          String operator + (const String&, const String&);

          void f(void)
          {
             char* p= "one" + "two"; // ill-formed because neither
                                     // operand has user defined type
             int I = 1 + 1;          // Always evaluates to 2 even if
                                     // user defined types exist which
                                     // would perform the operation.
          }
   --end example]

2 If either operand has a type that is a  class  or  an  enumeration,  a
  user-defined  operator function might be declared that implements this
  operator or a user-defined conversion can be necessary to convert  the
  operand  to  a  type  that is appropriate for a built-in operator.  In
  this case, overload resolution is used  to  determine  which  operator
  function  or builtin operator is to be invoked to implement the opera-
  tor.  Therefore, the operator notation is  first  transformed  to  the
  equivalent  function-call  notation  as summarized in Table 1 (where @
  denotes one of the operators covered in the specified subclause).

    Table 1--relationship between operator and function call notation

  +--------------+------------+--------------------+------------------------+
  |Subclause     | Expression | As member function | As non-member function
  |
  +--------------+------------+--------------------+------------------------+
  |_over.unary_  | @a         | (a).operator@ ()   | operator@ (a)
  |
  |_over.binary_ | a@b        | (a).operator@ (b)  | operator@ (a, b)
  |
  |_over.ass_    | a=b        | (a).operator= (b)  |
  |
  |_over.sub_    | a[b]       | (a).operator[](b)  |
  |
  |_over.ref_    | a->        | (a).operator-> ()  |
  |
  |_over.inc_    | a@         | (a).operator@ (0)  | operator@ (a, 0)
  |
  +--------------+------------+--------------------+------------------------+

3 For     a     type     T     whose     fully-qualified     name     is
  ::N1::...::Nn::C1::...::Cm::T  where  each  Ni is a namespace name and
  each  Ci  is  a  class  name,  the  fully-qualified   namespace   name
  ::N1::...::Nn  is  called the "namespace of the type T."  To look up X
  in the "context of the namespace of the type T" means to  perform  the
  qualified  name  lookup of ::N1::...::Nn::X (_over.call.func_), except
  that only names actually declared in the namespace are visible.  Names
  made  visible  by using-directives (_namespace.udir_) in the namespace
  are not considered.

  +-------                 BEGIN BOX 1                -------+
  Change: This last sentence is an  editorial  proposal.   The  Monterey
  resolution  17  changed the name look up rules for qualified namespace
  members. This last sentence ensure that the rule above keeps its  pre-
  Monterey meaning. See email message core-6081.
  +-------                  END BOX 1                 -------+

4 For a type T whose fully-qualified name is ::C1::...::Cm::T where each
  Ci is a class name, to look up X in the "context of the  namespace  of
  the  type T" means to perform the qualified name lookup of ::X, except
  that only names actually declared in global scope are visible.   Names
  made  visible  by  using-directives (_namespace.udir_) in global scope
  are not considered.

  +-------                 BEGIN BOX 2                -------+
  Change: This previous paragraph is an editorial proposal.  This  para-
  graph  was  added to correctly handle classes defined in global scope.
  Otherwise, the new operator look up rules  will  not  allow  operators
  defined in global scope to be found if the type of one of the operands
  is a class from global scope. See email message core-6082.
  +-------                  END BOX 2                 -------+

5 For a unary operator @ with an operand of type T1 or reference  to  cv
  T1, and for a binary operator @ with a left operand of type T1 or ref-
  erence to cv T1 and a right operand of type T2 or reference to cv  T2,

  three  sets of candidate functions, designated member candidates, non-
  member candidates and built-in candidates, are constructed as follows:

  --If T1 is a class type, the set of member candidates is the result of
    the qualified lookup of T1::operator@ (_over.call.func_); otherwise,
    the set of member candidates is empty.

  --The set of non-member candidates is the union of the functions found
    in the following name lookups:

    --The unqualified operator@ is looked  up  in  the  context  of  the
      expression  according  to  the  usual rules for name lookup except
      that all member functions are ignored.

    --For each type Z, where Z is a class type representing either T1 or
      T2,  or  a  direct  or  indirect base class of one of these types,
      operator@ is looked up in the context of the namespace of  type  Z
      according to the usual rules for name lookup.

    --For each type Z, where Z is an enumeration type representing T1 or
      T2, operator@ is looked up in the context of the namespace of that
      type according to the usual rules for name lookup.

...

Jason
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Technical Details
Message-ID: <u9ag75e27b.fsf@yorick.cygnus.com>
Path: arc1-ca.pugleaf.net!in2.uu.net!bounce-back
References: <45as8l$mf8@rational.rational.com> <45cp5c$sd@oznet03.ozemail.com.au> <45jbct$qv9@rational.rational.com>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!in2.uu.net!bounce-back
Date: 13 Oct 95 18:00:54 GMT
Approved: fjh@cs.mu.oz.au
From: jason@cygnus.com (Jason Merrill)
Newsgroups: comp.std.c++
Subject: Re: STL <iostream> vs. <iostream.h>
X-Original-Date: 13 Oct 1995 10:14:00 -0700
Organization: Cygnus Support, Mountain View, CA
Sender: jason@cygnus.com
Message-ID: <u9ag75e27b.fsf@yorick.cygnus.com>
References: <45as8l$mf8@rational.rational.com>
 <45cp5c$sd@oznet03.ozemail.com.au> <45jbct$qv9@rational.rational.com>
In-Reply-To: "Jirtme Desquilbet"'s message of 13 Oct 95 01:55:30 GMT
X-Newsreader: Gnus v5.0
X-Auth: PGPMoose V1.0 PGP comp.std.c++
 iQBFAgUBMH6pfeEDnX0m9pzZAQHmIQGAl6u2gsh+Xam4P8RL8+AtNDr2HCAxcapE
 PMyTqi8KnJnKLOOexpnsC8kAW1hKgFmg
 =t26y