[cfe-dev] Visibility of inline defined friend template function

Will Wilson will at indefiant.com
Sun Aug 25 11:23:53 PDT 2013


Apologies, for the delay - this had to go on the backburner for a while.
Here are my results with MSVC 10...

*Test 1: Original*

class S {
public:
  friend void f() {}
  template<typename T> friend void g(T&) {}
};
void h() {
  f(); // error C3767: 'f': candidate function(s) not accessible \
       // could be the friend function at 'friend_functions_inline.cpp(58)'
: 'f'  [may be found via argument-dependent lookup]

  g(S()); // warning C4239: nonstandard extension used : 'argument' :
conversion from 'S' to 'S &'

  g<S>(S{}); // error C2143: syntax error : missing ')' before '{'

  g<int>(0); // error C3767: 'g': candidate function(s) not accessible \
             // could be the friend function at
'friend_functions_inline.cpp(59)' : 'g'  [may be found via
argument-dependent lookup]
}

*Test 2: Added variables f & g*

int f, g;

class S {
public:
  friend void f() {} // error C2365: 'f' : redefinition; previous
definition was 'data variable'
  template<typename T> friend void g(T&) {} //
friend_functions_inline.cpp(61) : error C2365: 'g' : redefinition; previous
definition was 'data variable' \
   // friend_functions_inline.cpp(56) : see declaration of 'g' \
   // friend_functions_inline.cpp(61) : error C2904: 'g' : name already
used for a template in the current scope \
   // friend_functions_inline.cpp(56) : see declaration of 'g'
};
void h() {
  f();          // error C2064: term does not evaluate to a function taking
0 arguments
  g(S()); // error C2064: term does not evaluate to a function taking 1
arguments
  g<S>(S{}); // [various errors - template not resolved]
  g<int>(0); // error C2062: type 'int' unexpected
 }

*Test 3: Enclosing namespace*
*
*
This results in the same output as test 2 but with the namespace
qualification in the errors.

I hope that provides some insight.

- Will.


On 9 July 2013 23:46, Richard Smith <richard at metafoo.co.uk> wrote:

> On Tue, Jul 9, 2013 at 2:32 PM, Will Wilson <will at indefiant.com> wrote:
> > Thanks Richard. [temp.arg.explicit]p8 uses namespaces in the example
> which
> > threw me. Anyhow, I'll take a look at adding support for this when in MS
> > mode. I assume it shouldn't be too hard to do...?
>
> Does MSVC perform friend injection in general, or does it just somehow
> manage to parse DoT as a template name in this case? For instance:
>
> struct S {
>   friend void f() {}
>   template<typename T> friend void g(T) {}
> };
> void h() {
>   f(); // ok?
>   g(S()); // ok?
>   g<S>(S{}); // ok?
>   g<int>(0); // ok?
> }
>
> ... and what happens if you add:
>
>   int f, g;
>
> prior to the class definition? What happens if you add them to an
> enclosing namespace?
>
> > On 9 July 2013 22:17, Richard Smith <richard at metafoo.co.uk> wrote:
> >>
> >> On Tue, Jul 9, 2013 at 8:38 AM, Will Wilson <will at indefiant.com> wrote:
> >> > Hi All,
> >> >
> >> > A quick question regarding correct behaviour:
> >> >
> >> > class Vec3 {
> >> > public:
> >> > friend void DoA(Vec3& a) {
> >> > a.m_int = 1;
> >> > }
> >> >
> >> > template <const bool B>
> >> > friend void DoT(Vec3& a) {
> >> > if (B)
> >> > a.m_int = 2;
> >> > }
> >> > private:
> >> > int m_int;
> >> > };
> >> >
> >> > void test_friend_functions_inline() {
> >> > Vec3 a;
> >> > DoA(a);
> >> > DoT<true>(a);  // error: use of undeclared identifier 'DoT'
> >>
> >> Lookup of DoT here finds nothing, so this is parsed as a comparison
> >> rather than as a template. EDG rejects this in its strict mode.
> >>
> >> See [temp.arg.explicit]p8, which has almost exactly this case as an
> >> example.
> >
> >
> >
> >
> > --
> > Indefiant Ltd.
> >
> > Firsby Lodge, New Main Road, Scamblesby, Louth, Lincs LN11 9XH UK
> > Tel: +44 20 8123 7663 England Registered No. 07936820 VAT No. 128556202
>



-- 
*Indefiant Ltd.*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130825/62ad59b4/attachment.html>


More information about the cfe-dev mailing list