Topic: Linkage of friends of templates


Author: v.Abazarov@attAbi.com ("Victor Bazarov")
Date: Wed, 30 Apr 2003 22:53:26 +0000 (UTC)
Raw View
"Allan W" <allan_w@my-dejanews.com> wrote...
> > > Scott Meyers <Usenet@aristeia.com> schrieb
> > > > Suppose I have a class template that declares a friend function that
is
> > > > completely defined within the template, e.g.,
> > > >
> > > >   template<typename T>
> > > >   class rational {
> > > >
> > > >     friend bool operator>(const rational& lhs, const rational& rhs)
> > > >     { return true; }
> > > >
> > > >   };
>
> > "Matthias Hofmann" <hofmann@anvil-soft.com> wrote...
> > > Excuse me for digressing a bit from the original question, but as I
have
> > > rarely seen an example as the one above, I have another question:
> > >
> > > [...]
> > > And one more thing confuses me: As operator> is declared within
> > > a class template, doesn't that make operator> a template function
> > > as well? One that takes two "const rational<T>&" as arguments?
>
> v.Abazarov@attAbi.com ("Victor Bazarov") wrote
> > No.  It's not a member function.  And since there is no "template"
> > at the beginning of its declaration/definition, it is not a template.
>
> But the argument types *are* both const rational<T>&, right?


You're right...  It does make it a template, doesn't it?... Does
that mean that 'T' is actually defined in the body of that operator?
It seems that it shouldn't be.  The point is that you cannot
explicitly instantiate such function.  Or specialise it.  But once
it's implicitly instantiated, there is no 'T', the arguments have
concrete types.  Weird...

Victor
--
Please remove capital A's from my address when replying by mail


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Thu, 1 May 2003 19:17:15 +0000 (UTC)
Raw View
On Wed, 30 Apr 2003 22:53:26 +0000 (UTC), v.Abazarov@attAbi.com ("Victor
Bazarov") wrote:

> "Allan W" <allan_w@my-dejanews.com> wrote...

> > But the argument types *are* both const rational<T>&, right?

> You're right...  It does make it a template, doesn't it?

Not really.

> ... Does
> that mean that 'T' is actually defined in the body of that operator?
> It seems that it shouldn't be.  The point is that you cannot
> explicitly instantiate such function.  Or specialise it.  But once
> it's implicitly instantiated, there is no 'T', the arguments have
> concrete types.  Weird...

Not that strange.  When the class is instantiated, the friend for that T
is instantiated.  Whether it is used or not and whether it is valid or not,
it is instantiated.  Template functions are only instantiated if used.
This is not a template.  It is a non-template friend of this instantiation
of the template class.  Note that the explicit instantiation of the class
contains an explicit definition of its non-template friend.

John

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: v.Abazarov@attAbi.com ("Victor Bazarov")
Date: Tue, 29 Apr 2003 05:52:53 +0000 (UTC)
Raw View
"Matthias Hofmann" <hofmann@anvil-soft.com> wrote...
> Scott Meyers <Usenet@aristeia.com> schrieb in im Newsbeitrag:
> MPG.19163efcf2550ae59896d8@news.hevanet.com...
> > Suppose I have a class template that declares a friend function that is
> > completely defined within the template, e.g.,
> >
> >   template<typename T>
> >   class rational {
> >
> >     friend bool operator>(const rational& lhs, const rational& rhs)
> >     { return true; }
> >
> >   };
>
>
> Excuse me for digressing a bit from the original question, but as I have
> rarely seen an example as the one above, I have another question:
>
> As operator> is obviously private,

It's not a member, it's a friend.  Access specifiers do not apply here.

> [...]
> And one more thing confuses me: As operator> is declared within a class
> template, doesn't that make operator> a template function as well? One
that
> takes two "const rational<T>&" as arguments?

No.  It's not a member function.  And since there is no "template"
at the beginning of its declaration/definition, it is not a template.

Victor
--
Please remove capital A's from my address when replying by mail


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Wed, 30 Apr 2003 17:29:26 +0000 (UTC)
Raw View
> > Scott Meyers <Usenet@aristeia.com> schrieb
> > > Suppose I have a class template that declares a friend function that is
> > > completely defined within the template, e.g.,
> > >
> > >   template<typename T>
> > >   class rational {
> > >
> > >     friend bool operator>(const rational& lhs, const rational& rhs)
> > >     { return true; }
> > >
> > >   };

> "Matthias Hofmann" <hofmann@anvil-soft.com> wrote...
> > Excuse me for digressing a bit from the original question, but as I have
> > rarely seen an example as the one above, I have another question:
> >
> > [...]
> > And one more thing confuses me: As operator> is declared within
> > a class template, doesn't that make operator> a template function
> > as well? One that takes two "const rational<T>&" as arguments?

v.Abazarov@attAbi.com ("Victor Bazarov") wrote
> No.  It's not a member function.  And since there is no "template"
> at the beginning of its declaration/definition, it is not a template.

But the argument types *are* both const rational<T>&, right?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hofmann@anvil-soft.com ("Matthias Hofmann")
Date: Wed, 30 Apr 2003 17:32:30 +0000 (UTC)
Raw View
"Victor Bazarov" <v.Abazarov@attAbi.com> schrieb in im Newsbeitrag:
var27l7ghbgd41@corp.supernews.com...
> "Matthias Hofmann" <hofmann@anvil-soft.com> wrote...
> > Scott Meyers <Usenet@aristeia.com> schrieb in im Newsbeitrag:
> > MPG.19163efcf2550ae59896d8@news.hevanet.com...
> > > Suppose I have a class template that declares a friend function that
is
> > > completely defined within the template, e.g.,
> > >
> > >   template<typename T>
> > >   class rational {
> > >
> > >     friend bool operator>(const rational& lhs, const rational& rhs)
> > >     { return true; }
> > >
> > >   };
> >
> >
> > Excuse me for digressing a bit from the original question, but as I have
> > rarely seen an example as the one above, I have another question:
> >
> > As operator> is obviously private,
>
> It's not a member, it's a friend.  Access specifiers do not apply here.
>
> > [...]
> > And one more thing confuses me: As operator> is declared within a class
> > template, doesn't that make operator> a template function as well? One
> that
> > takes two "const rational<T>&" as arguments?
>
> No.  It's not a member function.  And since there is no "template"
> at the beginning of its declaration/definition, it is not a template.

But if operator> is not a template function, its parameters (two const
rationl& ) are not templatized either? How can the following example work
then?

template <typename T>
bool f( const rational<T>& r1, const rational<T>& r2 )
{
    return r1 > r2;
}

The comparison in the function's body should be equivalent to

return operator>( r1, r2 );

But doesn't this mean that references to a template class are passed to a
function that has no template arguments?

Regards,

Matthias




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: v.Abazarov@attAbi.com ("Victor Bazarov")
Date: Wed, 30 Apr 2003 17:53:29 +0000 (UTC)
Raw View
"Matthias Hofmann" <hofmann@anvil-soft.com> wrote...
> "Victor Bazarov" <v.Abazarov@attAbi.com> schrieb in im Newsbeitrag:
> var27l7ghbgd41@corp.supernews.com...
> > "Matthias Hofmann" <hofmann@anvil-soft.com> wrote...
> > > Scott Meyers <Usenet@aristeia.com> schrieb in im Newsbeitrag:
> > > MPG.19163efcf2550ae59896d8@news.hevanet.com...
> > > > Suppose I have a class template that declares a friend function that
> is
> > > > completely defined within the template, e.g.,
> > > >
> > > >   template<typename T>
> > > >   class rational {
> > > >
> > > >     friend bool operator>(const rational& lhs, const rational& rhs)
> > > >     { return true; }
> > > >
> > > >   };
> > >
> > >
> > > Excuse me for digressing a bit from the original question, but as I
have
> > > rarely seen an example as the one above, I have another question:
> > >
> > > As operator> is obviously private,
> >
> > It's not a member, it's a friend.  Access specifiers do not apply here.
> >
> > > [...]
> > > And one more thing confuses me: As operator> is declared within a
class
> > > template, doesn't that make operator> a template function as well? One
> > that
> > > takes two "const rational<T>&" as arguments?
> >
> > No.  It's not a member function.  And since there is no "template"
> > at the beginning of its declaration/definition, it is not a template.
>
> But if operator> is not a template function, its parameters (two const
> rationl& ) are not templatized either? How can the following example work
> then?
>
> template <typename T>
> bool f( const rational<T>& r1, const rational<T>& r2 )
> {
>     return r1 > r2;
> }
>
> The comparison in the function's body should be equivalent to
>
> return operator>( r1, r2 );
>
> But doesn't this mean that references to a template class are passed to a
> function that has no template arguments?

No references to a template class are passed anywhere.  When time
comes to pass references, there are no template classes.  Both
types are specialised due to implicit instatiation.

MHO is that it's a special case.  It's not a template because
there are no template arguments defined for that function (and
it cannot make use of 'T', can it?*) and unlike the real templates,
this function cannot be explicitly instantiated or specialised.
It is a template in the sense that when needed it is imlicitly
instantiated with concrete types.  But it's not fully a template
like the class or its members are.

*) The scope of a friend function defined in the class definition
is the namespace of the class, so no names declared in the class
are available in the function directly.

Victor
--
Please remove capital A's from my address when replying by mail


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Usenet@aristeia.com (Scott Meyers)
Date: Mon, 28 Apr 2003 03:27:48 +0000 (UTC)
Raw View
Suppose I have a class template that declares a friend function that is
completely defined within the template, e.g.,

  template<typename T>
  class rational {

    friend bool operator>(const rational& lhs, const rational& rhs)
    { return true; }

  };

Since each operator> is a non-template non-member function, I'm assume that
each has external linkage.  In practice, however, with the two compilers I
have working here (g++ 3.2 and VC 7.1), I find that if I compile multiple
translation units such that a particular operator> function is used in
both, I can link the two object files together and not get any kind of
complaint about a multiply defined system.  That suggests that maybe each
operator> function has internal linkage.  So, as usual, I'm confused.

Questions:
  1. What kind of linkage does each operator> have?
  2. Where is that specified in the standard?
  3. If the linkage is external, why am I not getting a link-time error
     in my simple experiments?  I have already verified that each object
     file I'm linking has its own externally visible copy of the function.

Thanks,

Scott

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: v.Abazarov@attAbi.com ("Victor Bazarov")
Date: Mon, 28 Apr 2003 06:16:05 +0000 (UTC)
Raw View
"Scott Meyers" <Usenet@aristeia.com> wrote...
> Suppose I have a class template that declares a friend function that is
> completely defined within the template, e.g.,
>
>   template<typename T>
>   class rational {
>
>     friend bool operator>(const rational& lhs, const rational& rhs)
>     { return true; }
>
>   };
>
> Since each operator> is a non-template non-member function, I'm assume
that
> each has external linkage.  In practice, however, with the two compilers I
> have working here (g++ 3.2 and VC 7.1), I find that if I compile multiple
> translation units such that a particular operator> function is used in
> both, I can link the two object files together and not get any kind of
> complaint about a multiply defined system.  That suggests that maybe each
> operator> function has internal linkage.  So, as usual, I'm confused.
>
> Questions:
>   1. What kind of linkage does each operator> have?

External.

>   2. Where is that specified in the standard?

11.4/3

>   3. If the linkage is external, why am I not getting a link-time error
>      in my simple experiments?  I have already verified that each object
>      file I'm linking has its own externally visible copy of the function.

Any friend function defined in the class scope is implicitly
'inline' (11.4/5), and any function specified as 'inline' has
the same address in all translation units where it's declared
(7.1.2/4).  That basically forces the compiler to merge all
implementations of that function.  If you can see the addresses
of those functions and they are different, the compilers are
non-compliant (IMHO, at least that's how I read the Standard).

Victor
--
Please remove capital A's from my address when replying by mail

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: stephen.clamage@sun.com (Stephen Clamage)
Date: Mon, 28 Apr 2003 07:15:53 +0000 (UTC)
Raw View
On Mon, 28 Apr 2003 03:27:48 +0000 (UTC), Usenet@aristeia.com (Scott
Meyers) wrote:

>Suppose I have a class template that declares a friend function that is
>completely defined within the template, e.g.,
>
>  template<typename T>
>  class rational {
>
>    friend bool operator>(const rational& lhs, const rational& rhs)
>    { return true; }
>
>  };
>
>Since each operator> is a non-template non-member function, I'm assume that
>each has external linkage.

Right. Because you haven't done anything to cause it to have internal
linkage. A function has external linkage unless you declare it static,
or if it is a member of a class local to a function.

>  In practice, however, with the two compilers I
>have working here (g++ 3.2 and VC 7.1), I find that if I compile multiple
>translation units such that a particular operator> function is used in
>both, I can link the two object files together and not get any kind of
>complaint about a multiply defined system.  That suggests that maybe each
>operator> function has internal linkage.

Consider any template defined in a header that is included in multiple
translation units. It could get instantiated on the same type more
than once. The compiler needs to have some mechanism to deal with
multiple copies of what must be a single global instance in the final
program.

A common solution is to emit template instances into a special address
section in the object code. The compiler and linker agree that
multiple definitions in that address section are OK, and that only one
copy will be retained.

Another solution is to emit template instances one per file into a
special directory. When an instance is needed, the template repository
is checked, and a new instance emitted if an up to date version is not
already present. At link time, the repository is automatically
searched for needed instances, and additional instances generated if
needed.

Compilers often document the method of template generation they use.

---
Steve Clamage, stephen.clamage@sun.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hofmann@anvil-soft.com ("Matthias Hofmann")
Date: Mon, 28 Apr 2003 18:52:55 +0000 (UTC)
Raw View
Scott Meyers <Usenet@aristeia.com> schrieb in im Newsbeitrag:
MPG.19163efcf2550ae59896d8@news.hevanet.com...
> Suppose I have a class template that declares a friend function that is
> completely defined within the template, e.g.,
>
>   template<typename T>
>   class rational {
>
>     friend bool operator>(const rational& lhs, const rational& rhs)
>     { return true; }
>
>   };


Excuse me for digressing a bit from the original question, but as I have
rarely seen an example as the one above, I have another question:

As operator> is obviously private, would it be possible to use it like:

template <typename T>
bool f( const rational<T>& r1, const rational<T>& r2 )
{
    return r1 > r2;
}

If not, why would anyone declare such an operator private within a class?

And one more thing confuses me: As operator> is declared within a class
template, doesn't that make operator> a template function as well? One that
takes two "const rational<T>&" as arguments?

Best regards,

Matthias



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]