Re: Question related to changes in template handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 Thanks, this clears things up (sorry for the botched formatting of the original mail).This also explains why clang handles the code the same way as g++12.
Regards
Klaus
    Am Sonntag, 22. Mai 2022, 20:22:28 MESZ hat Jonathan Wakely <jwakely.gcc@xxxxxxxxx> Folgendes geschrieben:  
 
 On Sun, 22 May 2022 at 18:25, Klaus Lindemann via Gcc-help
<gcc-help@xxxxxxxxxxx> wrote:
>
> Hello,
> was the handling of templates changed for g++12? I've run across some programs
> which did compile with e.g. g++8, g++11, but no longer compile with g++12.
> The fix is quite easy, but I wonder if this change is a bug, or a more strict
> implementation of the standard.
> Here is a short example program:================================================// compiles with g++ 11, not g++ 12
> #include <vector>namespace NN  // if namespace is removed (i.e. global namespace is used), problem does not occur{  class OStr {};}
> template <class T> NN::OStr& operator<<(NN::OStr& lhs, const std::vector<T>& rhs) { return lhs << rhs[0]; }
> // moving this definition before the other template definition fixes gcc 12 compile problemtemplate <class T> NN::OStr& operator<< (NN::OStr& lhs, const T& rhs) { return lhs << rhs; }
> int main(){  std::vector<int> a;  NN::OStr os;  os << a;  return 0;}=================================================


Reformatted so it's not illegible:

#include <vector>
namespace NN
// if namespace is removed (i.e. global namespace is used),
// problem does not occur
{
  class OStr {};
}
template <class T>
NN::OStr& operator<<(NN::OStr& lhs, const std::vector<T>& rhs)
{ return lhs << rhs[0]; }
// moving this definition before the other template definition
// fixes gcc 12 compile problem
template <class T>
NN::OStr& operator<< (NN::OStr& lhs, const T& rhs) { return lhs << rhs; }

int main(){
  std::vector<int> a;
  NN::OStr os;
  os << a;
  return 0;
}

GCC 12 is correct. Your code is wrong.

In the expression lhs << rhs[0], name lookup is done for operator<< by
considering the overloads already visible at that point, and overloads
that can be found by ADL in the associated namespaces. The associated
namespaces for OStr and int are NN, and there is no viable overload in
namepace NN.

An operator that is part of the API of NN::OStr should be defined in
namespace NN, not the global namespace. If you define both your
operator<< overloads in the same namespace as class OStr it will work.

N.B. this lookup is consistent for the non-template case, because GCC
12 has been fixed to stop looking in the global namespace when that is
not an associated namespace.
  




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux