C++ Logo

STD-DISCUSSION

Advanced search

Subject: Re: Friend template operator declaration.
From: Omry Noam (omrynoam_at_[hidden])
Date: 2021-04-22 02:50:44


Comparing the codes between compilers:
For the first code:

gcc compiles with a warning:
<source>:19:70: warning: friend declaration 'std::ostream&
operator<<(std::ostream&, const A<T>&)' declares a non-template function
[-Wnon-template-friend]
   19 | friend std::ostream &::operator <<( std::ostream &, const A<T>
& );

clang compiles without warnings.

icc compiles with two warnings:
<source>(19): warning #1098: the qualifier on this friend declaration is
ignored
      friend std::ostream &::operator <<( std::ostream &, const A<T> & );
                           ^
<source>(19): warning #1624: "std::ostream &operator<<(std::ostream &,
const A<T> &)" declares a non-template function -- add <> to refer to a
template instance
      friend std::ostream &::operator <<( std::ostream &, const A<T> & );

And only msvc rejects the code:
<source>(19): error C2063: 'operator <<': not a function

For the second code, only msvc's behavior changes, and it now compiles
without warnings.

(All tested on trunk/latest version available on godbolt, for x86)

On Thu, Apr 22, 2021 at 9:49 AM Vladimir Grigoriev via Std-Discussion <
std-discussion_at_[hidden]> wrote:

> Bo, I provided a reference that says about deduced template
> specialization. It is the case. That is if in a friend declaration there is
> used a qualified name (not a template-id) and a corresponding template
> declaration is found then the friend declaration is a templated
> specialization.
>
>
> You can meet me at http://cpp.forum24.ru/ or www.stackoverflow.com or
> http://ru.stackoverflow.com
>
>
>
> Четверг, 22 апреля 2021, 9:34 +03:00 от Bo Persson via Std-Discussion <
> std-discussion_at_[hidden]>:
>
> On 2021-04-21 at 23:21, Vladimir Grigoriev via Std-Discussion wrote:
> > The following program does not compile in MS Visual Studio 19.
> >
> > |#include <iostream> #include <string> template <typename T> class A;
> > template <typename T> std::ostream &operator <<( std::ostream &, const
> > A<T> & ); template <typename T> class A { private: T x; public: A( const
> > T &x ) : x( x ) {} friend std::ostream &::operator <<( std::ostream &,
> > const A<T> & ); }; template <typename T> std::ostream &operator <<(
> > std::ostream &os, const A<T> &a ) { return os << "a.x = " << a.x; } int
> > main() { std::cout << A<std::string>( "Hello" ) << '\n'; } |
> >
> > The compiler says that operator << is not a function.
> >
> > While the following program
> >
> > |#include <iostream> #include <string> template <typename T> class A;
> > template <typename T> std::ostream &f( std::ostream &, const A<T> & );
> > template <typename T> class A { private: T x; public: A( const T &x ) :
> > x( x ) {} friend std::ostream &::f( std::ostream &, const A<T> & ); };
> > template <typename T> std::ostream &f( std::ostream &os, const A<T> &a )
> > { return os << "a.x = " << a.x; } int main() { f( std::cout,
> > A<std::string>( "Hello" ) ) << '\n'; } |
> >
> > compiles successfully.
> >
> > What is the reason of that the first program does not compile? Is it a
> > bug of MS Visual Studio 19 or do I have missed something from the C++ 20
> > Standard?
> >
> > You can meet me at http://cpp.forum24.ru/ or www.stackoverflow.com or
> > http://ru.stackoverflow.com
> >
>
> I don't know the exact rule, but note that the friend is not a template,
> while the global operator is.
>
> MSVC accepts the code if you change it to
>
> template<typename U>
> friend std::ostream &::operator <<( std::ostream &, const A<U> & );
>
>
>
>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> <http:///compose?To=Std%2dDiscussion@lists.isocpp.org>
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>



STD-DISCUSSION list run by std-discussion-owner@lists.isocpp.org

Older Archives on Google Groups