On Fri, Jul 12, 2024 at 12:10 PM Dalbey, Keith via Gcc <gcc@gcc.gnu.org> wrote:
>
> The means by which this FIX was implemented caused OTHER problems
>
> template <typename F, typename S>
> std::ostream& operator<<(std::ostream& os, const std::pair<F,S>& pr)
> {
>         os << "(" << pr.first << ", " << pr.second << ")";
>         return os;
> }


You could just do:
```
template <typename F, typename S>
std::ostream& operator<<(std::ostream& os, const std::pair<F,S>& pr);
....
//include all other headers
template <typename F, typename S>
std::ostream& operator<<(std::ostream& os, const std::pair<F,S>& pr)
{
         os << "(" << pr.first << ", " << pr.second << ")";
         return os;
}
```
And then it will work correctly.
But now this is getting into C++ help rather than GCC help really.

Thanks,
Andrew

>
> Will only work for CONCRETE classes that take the place of "F" and "S" IFF 
> each of their concrete operator<< 's is FORWARD DECLARED ahead of the above 
> template, so primitives like int and double should still work,  but if you 
> include this file in a header file that contains a concrete class that you 
> define an operator<< for, and then use in another file, you're SOL.
>
> If you mix that with templated operator<< for vectors and std::shared_ptr  
> then there's a chicken and the egg problem for which STL templated operator<< 
> gets declared first/ but you can work around this by FORWARD declaring all of 
> your operator<< (including the concrete and templated ones) before 
> **Defining** the STL templated operator<< 's, but that means the header file 
> containing the STL templated operator<< 's can never be included in another 
> header file and it can only be included as *the absolute last header file* in 
> a .cpp file (so that all the concrete operator<< get declared before them, 
> and you may still need to forward declare some of the contents of the .cpp 
> file ahead of including this header file)
>
> But really a header file that can't be included in other header files and can 
> only be included as the absolute last header file in a .cpp file is a 
> unreasonable set of hoops to jump through to get TEMPLATED operator<< 's to 
> work, which should just work BECAUSE THEY'RE TEMPLATES
>
> -----Original Message-----
> From: Jonathan Wakely <jwakely....@gmail.com>
> Sent: Friday, July 12, 2024 12:37 PM
> To: Dalbey, Keith <kdal...@sandia.gov>
> Cc: gcc@gcc.gnu.org
> Subject: [EXTERNAL] Re: g++12 broke my system of overloaded operator<<
>
> [You don't often get email from jwakely....@gmail.com. Learn why this is 
> important at https://aka.ms/LearnAboutSenderIdentification ]
>
> On Fri, 12 Jul 2024 at 01:03, Dalbey, Keith via Gcc <gcc@gcc.gnu.org> wrote:
> >
> > So I'm on redhat 7 and just got devtoolsset-12 and code (a system of
> > overloaded<< operators) that was working with devtoolset-10 now break
> > (because of ordering)
> >
> > To not bury the lead..
> >
> > My code relies on the version 11 or older behavior (see below), and I don't 
> > see how anyone could call the new behavior an improvement or correction 
> > because it neuters/cancels out  the power/flexibility of the STL.   Yes one 
> > could technically work around it by forward declaring templated operator<<  
> > but that makes the system not extensible,  a common package/gitlab project 
> > that handles this for the STL and then gets succeed into another library 
> > that overloads the operator<< for concrete classes just doesn't work any 
> > more... and that was my exact use case.
> >
> > Please reverse this change in future editions of gcc, it is absolutely 
> > awful.
>
> Why would you want the example below to behave differently for
> operator+(t, 0) and t+0 when they're two different ways to spell the
> same function call?
>
> The old behaviour was clearly a bug, and thankfully has been fixed.
> See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51577 for the bug report I 
> made about it years ago, which has a large number of duplicates because other 
> people also reported the old behaviour as a bug. Because it was a bug, and 
> people wanted GCC to follow the C++ standard.
>
> I'm sorry you've written code that depends on a bug, but we're not going to 
> break GCC again to restore the bug.
>
>
> >
> > From this link
> > https://deve/
> > lopers.redhat.com%2Farticles%2F2022%2F04%2F25%2Fnew-c-features-gcc-12%
> > 23corrections_and_internal_improvements&data=05%7C02%7Ckdalbey%40sandi
> > a.gov%7Cc1e76e1166844e639bc208dca2a1aa33%7C7ccb5a20a303498cb0c12900738
> > 1b574%7C1%7C0%7C638564062475549377%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4
> > wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&s
> > data=KxNgv9u%2BDq8toLCNArhF1xjc1tHoP2Dy%2BYEv5P2gMXo%3D&reserved=0
> > Corrections and internal improvements
> > The changes described in this section bring GCC more in line with recent 
> > changes to the standard, and permit behavior that previously did not work 
> > correctly.
> > Dependent operator lookup changes
> > GCC 12 corrected a problem where the compiler performed an unqualified 
> > lookup for a dependent operator expression at template definition time 
> > instead of at instantiation time. The fix matches the existing behavior for 
> > dependent call expressions. Consider the following test case demonstrating 
> > this change:
> > #include <iostream>
> >
> > namespace N {
> >   struct A { };
> > }
> >
> > void operator+(N::A, double) {
> >   std::cout << "#1 ";
> > }
> >
> > template<class T>
> > void f(T t) {
> >   operator+(t, 0);
> >   t + 0;
> > }
> >
> > // Since it's not visible from the template definition, this
> > later-declared // operator overload should not be considered when
> > instantiating f<N::A>(N::A), // for either the call or operator expression.
> > void operator+(N::A, int) {
> >   std::cout << "#2 ";
> > }
> >
> > int main() {
> >   N::A a;
> >   f(a);
> >   std::cout << std::endl;
> > }
> > Copy snippet
> > This program will print #1 #2 when compiled with versions 11 or older of 
> > GCC, but GCC 12 correctly prints #1 #1. That's because previously only the 
> > call expression resolved to the #1 overload, but with GCC 12 the operator 
> > expression does too.

Reply via email to