<div dir="ltr">On Sun, Aug 25, 2013 at 11:23 AM, Will Wilson <span dir="ltr"><<a href="mailto:will@indefiant.com" target="_blank">will@indefiant.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Apologies, for the delay - this had to go on the backburner for a while. Here are my results with MSVC 10...<div>

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



<div><br></div><div>  g(S()); // warning C4239: nonstandard extension used : 'argument' : conversion from 'S' to 'S &'</div></div></div></div></blockquote><div><br></div><div>Presumably this is accepted if you use g(T) not g(T&) on line 4?</div>

<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div><div>  g<S>(S{}); // error C2143: syntax error : missing ')' before '{'</div>

</div></div></div></blockquote><div><br></div><div>Is this accepted if you use S() not S{} ?</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr">
<div><div><div>  g<int>(0); // error C3767: 'g': candidate function(s) not accessible \</div><div>             // could be the friend function at 'friend_functions_inline.cpp(59)' : 'g'  [may be found via argument-dependent lookup]</div>



<div>}</div></div><div><br></div><div><b>Test 2: Added variables f & g</b></div></div><div><span style="font-family:arial,sans-serif;font-size:13px"><br></span></div><div><div><font face="arial, sans-serif">int f, g;</font></div>


<div><font face="arial, sans-serif"><br>
</font></div><div><font face="arial, sans-serif">class S {</font></div><div><font face="arial, sans-serif">public:</font></div><div><font face="arial, sans-serif">  friend void f() {}<span style="white-space:pre-wrap">        </span>// error C2365: 'f' : redefinition; previous definition was 'data variable'</font></div>



<div><font face="arial, sans-serif">  template<typename T> friend void g(T&) {} // friend_functions_inline.cpp(61) : error C2365: 'g' : redefinition; previous definition was 'data variable' \</font></div>



<div><font face="arial, sans-serif">   // friend_functions_inline.cpp(56) : see declaration of 'g' \</font></div><div><font face="arial, sans-serif">   // friend_functions_inline.cpp(61) : error C2904: 'g' : name already used for a template in the current scope \</font></div>



<div><font face="arial, sans-serif">   // friend_functions_inline.cpp(56) : see declaration of 'g'</font></div><div><font face="arial, sans-serif">};</font></div><div><font face="arial, sans-serif">void h() {</font></div>



<div><font face="arial, sans-serif">  f();          // error C2064: term does not evaluate to a function taking 0 arguments</font></div><div><font face="arial, sans-serif">  g(S());<span style="white-space:pre-wrap">        </span>// error C2064: term does not evaluate to a function taking 1 arguments</font></div>



<div><font face="arial, sans-serif">  g<S>(S{});<span style="white-space:pre-wrap"> </span>// [various errors - template not resolved]</font></div><div><div><font face="arial, sans-serif">  g<int>(0);<span style="white-space:pre-wrap">     </span>// </font>error C2062: type 'int' unexpected</div>










</div>
<div><font face="arial, sans-serif">}</font></div><div style="font-family:arial,sans-serif;font-size:13px"><br></div></div><div><b>Test 3: Enclosing namespace</b></div><div><b><br></b></div><div>This results in the same output as test 2 but with the namespace qualification in the errors.</div>

</div></blockquote><div><br></div><div>Some more test cases:</div><div><br></div><div>1)</div><div><br></div><div>int f;</div><div>namespace N {</div><div>  class S {</div><div>    template<typename T> friend void f(T) {}</div>

<div>  };</div><div>  void g() {</div><div>    f(S());<br></div><div>    f<S>(S());</div><div>    f(0);</div><div>    f<int>(0);</div>
<div><br></div><div>    int k = f;</div><div>  }</div><div>}</div><div><br></div><div>2)</div><div><br></div><div>class S {</div><div>  template<typename T> friend void f(T) {}</div><div>};</div>
<div>namespace N {</div><div>  int f;</div><div>  void g() {</div><div>    f(S());<br></div><div>    f<S>(S());<br></div><div>    f(0);</div>
<div>    f<int>(0);</div><div>  }</div><div>}</div><div><br></div><div>3)</div><div><br></div><div><div>namespace M {</div><div>  class S {</div><div>    template<typename T> friend void f(T) {}</div><div>  };</div>
<div>}</div><div>void g() {<br></div><div>  f(M::S());<br></div><div>  f<M::S>(M::S());</div><div>  f(0);</div><div>  f<int>(0);</div><div>}</div></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr"><div>I hope that provides some insight.</div>
<div><br></div><div>- Will.</div></div><div class="gmail_extra"><div><div><br><br><div class="gmail_quote">On 9 July 2013 23:46, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>On Tue, Jul 9, 2013 at 2:32 PM, Will Wilson <<a href="mailto:will@indefiant.com" target="_blank">will@indefiant.com</a>> wrote:<br>



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


</div>
</font></span></div>
</blockquote></div><br></div></div>