2016-04-21 2:57 GMT+06:00 Richard Smith <rich...@metafoo.co.uk>: > rsmith added a comment. > > Sorry, I don't think this approach can work. Consider: > > template<typename T> struct X { > template<typename U> friend void f(T); > template<typename U> friend void f(U); > }; > > These two friend declarations declare different friend function templates, > but this transformation would incorrectly make them have the same type and > be redeclarations of each other. > > Yes, it's true, thank you for the example. I think dependent friend template functions should not be added into redeclaration chains.
I think the right thing here is to just accept that a friend function > template declared within a class template will not be part of the > corresponding redeclaration chain. But that's fine, so long as we don't try > to inject the function template into the surrounding scope -- when we come > to instantiate the class template, the instantiated friend function > template will have the right type and will be part of the relevant > redeclaration chain. > > Redeclaration chain of templates are useful for checking semantics of templates, not instantiated entities, which have own redeclaration chains. Particular task for which this fix should be useful is implementation of default template arguments of friend functions. Now clang do not allow to specify them, but the standard allow [temp.parap]p9 : "... If a friend function template declaration specifies a default template-argument, that declaration shall be a definition and shall be the only declaration of the function template in the translation unit". The mentioned condition could be checked using redeclaration chain of templates, if the chain was built correctly. The main problem related to the redeclaration chains is similar to that solved by http://reviews.llvm.org/D16989. Clang and GCC now treat friend function definitions differently. The following code: template<typename T1> void func(); template<typename T> struct C1 { template<typename T1> friend void func() {} }; int main(int argc, char *argv[]) { func<int>(); } produces error at link stage if GCC is used, due to unresolved reference to func<int>(). Clang compiles this code successfully, it sees the definition of func inside struct C1. GCC sees it only if host template is instantiated. It makes sense to finish http://reviews.llvm.org/D16989 first. Many of problems related to not-template friend functions seem to be applicable to templates as well. Thanks, --Serge <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail> Без вирусов. www.avast.com <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail> <#DDB4FAA8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits