So Edward, how does now the paragraph #1 of the section «13.7.4 Friends» looks?
 
 
You can meet me at http://cpp.forum24.ru/ or www.stackoverflow.com or http://ru.stackoverflow.com
 
 
Четверг, 22 апреля 2021, 20:22 +03:00 от Edward Catmur <ecatmur@googlemail.com>:
 
This was all changed substantially by P1787R6: Declarations and where to find them[1]. Since then, using <T> or <>  to specify that the friend in question is a template specialization is clearly necessary.
 
It's definitely an MSVC bug that it continues to reject after making that amendment, though. I responded[2] to your SO question with more background suited to a general audience.
 
 
On Thu, 22 Apr 2021 at 16:38, Vladimir Grigoriev via Std-Discussion <std-discussion@lists.isocpp.org> wrote:
Bo, by the way I asked the question at Stackoverflow
 
 
And it is interesting  to note that at once it was down voted and closed because most of readers of the question thought that the friend declaration is not a template declaration and as a result they concluded that the question is a duplicate question.:)
 
I was to reopen the question.
 
 
 
 
Четверг, 22 апреля 2021, 9:34 +03:00 от Bo Persson via Std-Discussion <std-discussion@lists.isocpp.org>:
 
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@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
 
--
Std-Discussion mailing list
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion