Topic: Declaring friendship via "using"'d name


Author: hsutter@gotw.ca (Herb Sutter)
Date: Tue, 8 Oct 2002 20:03:32 +0000 (UTC)
Raw View
On Tue, 8 Oct 2002 16:57:47 +0000 (UTC), jpotter@falcon.lhup.edu (John
Potter) wrote:
>>   namespace N1 {
>>     template<typename T> void f( T* x ) {
>>       // ... other stuff ...
>>       delete x;
>>     }
>>   }
>>
>>   namespace N2 {

>//>     using N1::f;
>      using namespace N1; // 3.4.1/2
>
>//>     template<> void f<int>( int* ); // A: ill-formed

>>     class Test {
>>       ~Test() { }
>>       friend void f<>( Test* x );   // B: ill-formed?
>>     };
>>   }
>
>> I strongly suspect, but don't have standardese to prove, that the friend
>> declaration in line B is ill-formed. Can someone show me the text that
>> allows or disallows line B?
>
>It was, but now isn't.  Can someone explain that logic?

(You're speaking of line A, right?) No, the specialization is ill-formed
both ways, with the using-declaration or the using-directive.

I'm pretty sure this boils down to "using is for name lookup, not for
declarations (e.g., specializations, friends)" but I just want a reality
check to make sure I'm teaching this right.

Herb

---
Herb Sutter (www.gotw.ca)

Convener, ISO WG21 - Secretary, ANSI J16             (www.gotw.ca/iso)
Contributing editor, C/C++ Users Journal             (www.gotw.ca/cuj)
C++ community program manager, Microsoft       (www.gotw.ca/microsoft)

Check out "THE C++ Seminar" - Oct 28-30, 2002  (www.thecppseminar.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: andreytarasevich@hotmail.com (Andrey Tarasevich)
Date: Tue, 8 Oct 2002 22:46:33 +0000 (UTC)
Raw View
Herb Sutter wrote:
> The following came up recently on comp.lang.c++.moderated (edited for
> brevity):
>
>   namespace N1 {
>     template<typename T> void f( T* x ) {
>       // ... other stuff ...
>       delete x;
>     }
>   }
>
>   namespace N2 {
>     using N1::f;
>
>     template<> void f<int>( int* ); // A: ill-formed
>
>     class Test {
>       ~Test() { }
>       friend void f<>( Test* x );   // B: ill-formed?
>     };
>   }
>
> I strongly suspect, but don't have standardese to prove, that the friend
> declaration in line B is ill-formed. Can someone show me the text that
> allows or disallows line B?

14.5.3/2 seems to get pretty close: "A friend declaration that is not a
template declaration and in which the name of the friend is an unqualified
'template-id' shall refer to a specialization of a function template
declared in the nearest enclosing namespace scope". This brings us to a
question about whether the using-declaration of 'f' in namespace 'N2' is a
"declaration enough" to satisfy the requirements of 14.5.3/2. If it is, then
line B should be fine.

Although I'm not 100% sure, I think that according to 7.3.3 and 14.5.3/2
line B is perfectly legal.

> Here's my reasoning: Writing "using" to pull the name into namespace N2
> merely allows code in N2 to use the name in a call without qualification
> (per 7.3.3). But just as declaring a specialization must be done in the
> namespace where the template really lives (hence line A is ill-formed), I
> suspect that declaring a specialization as a friend must likewise be done
> using the original namespace name, not obliquely through a "using". I see
> nothing in 7.3.3 that would permit this use. Is there?

Formally, 14.5.3/2 seems to be permitting this use. Unfortunately, the
example in 14.5.3/2 doesn't clarify this issue.

--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Wed, 9 Oct 2002 15:57:20 +0000 (UTC)
Raw View
On Tue, 8 Oct 2002 20:03:32 +0000 (UTC), hsutter@gotw.ca (Herb Sutter)
wrote:

> On Tue, 8 Oct 2002 16:57:47 +0000 (UTC), jpotter@falcon.lhup.edu (John
> Potter) wrote:
> >>   namespace N1 {
> >>     template<typename T> void f( T* x ) {
> >>       // ... other stuff ...
> >>       delete x;
> >>     }
> >>   }

> >>   namespace N2 {

> >//>     using N1::f;
> >      using namespace N1; // 3.4.1/2

> >//>     template<> void f<int>( int* ); // A: ill-formed

> >>     class Test {
> >>       ~Test() { }
> >>       friend void f<>( Test* x );   // B: ill-formed?
> >>     };
> >>   }
> >
> >> I strongly suspect, but don't have standardese to prove, that the friend
> >> declaration in line B is ill-formed. Can someone show me the text that
> >> allows or disallows line B?

> >It was, but now isn't.  Can someone explain that logic?

> (You're speaking of line A, right?) No, the specialization is ill-formed
> both ways, with the using-declaration or the using-directive.

No, I'm speaking of line B.  There is language to make line A
ill-formed.

> I'm pretty sure this boils down to "using is for name lookup, not for
> declarations (e.g., specializations, friends)" but I just want a reality
> check to make sure I'm teaching this right.

When Comeau accepts line B with the using-directive, I suspect there
may be something we do not understand.  It seems that *creating* a
specialization is different from granting friendship to an existing
entity.  3.4.1/2 clearly makes the function part of the global
namespace.  Why is the using-declaration different?

John

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hsutter@gotw.ca (Herb Sutter)
Date: Wed, 9 Oct 2002 17:53:11 +0000 (UTC)
Raw View
On Tue, 8 Oct 2002 22:46:33 +0000 (UTC), andreytarasevich@hotmail.com
(Andrey Tarasevich) wrote:
>Herb Sutter wrote:
>> The following came up recently on comp.lang.c++.moderated (edited for
>> brevity):
>>
>>   namespace N1 {
>>     template<typename T> void f( T* x ) {
>>       // ... other stuff ...
>>       delete x;
>>     }
>>   }
>>
>>   namespace N2 {
>>     using N1::f;
>>
>>     template<> void f<int>( int* ); // A: ill-formed
>>
>>     class Test {
>>       ~Test() { }
>>       friend void f<>( Test* x );   // B: ill-formed?
>>     };
>>   }
>>
>> I strongly suspect, but don't have standardese to prove, that the friend
>> declaration in line B is ill-formed. Can someone show me the text that
>> allows or disallows line B?
>
>14.5.3/2 seems to get pretty close: "A friend declaration that is not a
>template declaration and in which the name of the friend is an unqualified
>'template-id' shall refer to a specialization of a function template
>declared in the nearest enclosing namespace scope".
 ^^^^^^^^

OK, thanks. Then the question in this is the word "declared" -- in
particular, we already know we cannot declare a specialization of a template
in any other namespace but the original one.

Herb

---
Herb Sutter (www.gotw.ca)

Convener, ISO WG21 - Secretary, ANSI J16             (www.gotw.ca/iso)
Contributing editor, C/C++ Users Journal             (www.gotw.ca/cuj)
C++ community program manager, Microsoft       (www.gotw.ca/microsoft)

Check out "THE C++ Seminar" - Oct 28-30, 2002  (www.thecppseminar.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: andreytarasevich@hotmail.com (Andrey Tarasevich)
Date: Wed, 9 Oct 2002 18:35:16 +0000 (UTC)
Raw View
Herb Sutter wrote:
> On Tue, 8 Oct 2002 22:46:33 +0000 (UTC), andreytarasevich@hotmail.com
> (Andrey Tarasevich) wrote:
>>Herb Sutter wrote:
>>> The following came up recently on comp.lang.c++.moderated (edited for
>>> brevity):
>>>
>>>   namespace N1 {
>>>     template<typename T> void f( T* x ) {
>>>       // ... other stuff ...
>>>       delete x;
>>>     }
>>>   }
>>>
>>>   namespace N2 {
>>>     using N1::f;
>>>
>>>     template<> void f<int>( int* ); // A: ill-formed
>>>
>>>     class Test {
>>>       ~Test() { }
>>>       friend void f<>( Test* x );   // B: ill-formed?
>>>     };
>>>   }
>>>
>>> I strongly suspect, but don't have standardese to prove, that the friend
>>> declaration in line B is ill-formed. Can someone show me the text that
>>> allows or disallows line B?
>>
>>14.5.3/2 seems to get pretty close: "A friend declaration that is not a
>>template declaration and in which the name of the friend is an unqualified
>>'template-id' shall refer to a specialization of a function template
>>declared in the nearest enclosing namespace scope".
>  ^^^^^^^^
>
> OK, thanks. Then the question in this is the word "declared" -- in
> particular, we already know we cannot declare a specialization of a template
> in any other namespace but the original one.
> ...

I thought that 14.5.3/2 sold be read as "[...] shall refer to a
specialization of a function template, and this _function_ _template_ shall
be declared in the nearest enclosing namespace scope". In this case the
declaration in line B should be legal.

If we read 14.5.3/2 as "[...] shall refer to a specialization of a function
template, and this _specialization_ shall be declared in the nearest
enclosing namespace scope", then line B is ill-formed.

As I said above, I believe that the first version is the correct one. If I
understand you correctly, you seem to prefer the second one.

--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: hsutter@gotw.ca (Herb Sutter)
Date: Mon, 7 Oct 2002 23:08:31 +0000 (UTC)
Raw View
The following came up recently on comp.lang.c++.moderated (edited for
brevity):

  namespace N1 {
    template<typename T> void f( T* x ) {
      // ... other stuff ...
      delete x;
    }
  }

  namespace N2 {
    using N1::f;

    template<> void f<int>( int* ); // A: ill-formed

    class Test {
      ~Test() { }
      friend void f<>( Test* x );   // B: ill-formed?
    };
  }

I strongly suspect, but don't have standardese to prove, that the friend
declaration in line B is ill-formed. Can someone show me the text that
allows or disallows line B?

Here's my reasoning: Writing "using" to pull the name into namespace N2
merely allows code in N2 to use the name in a call without qualification
(per 7.3.3). But just as declaring a specialization must be done in the
namespace where the template really lives (hence line A is ill-formed), I
suspect that declaring a specialization as a friend must likewise be done
using the original namespace name, not obliquely through a "using". I see
nothing in 7.3.3 that would permit this use. Is there?

Thanks,

Herb


---
Herb Sutter (www.gotw.ca)

Convener, ISO WG21 - Secretary, ANSI J16             (www.gotw.ca/iso)
Contributing editor, C/C++ Users Journal             (www.gotw.ca/cuj)
C++ community program manager, Microsoft       (www.gotw.ca/microsoft)

Check out "THE C++ Seminar" - Oct 28-30, 2002  (www.thecppseminar.com)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Tue, 8 Oct 2002 16:57:47 +0000 (UTC)
Raw View
On Mon, 7 Oct 2002 23:08:31 +0000 (UTC), hsutter@gotw.ca (Herb Sutter)
wrote:

>   namespace N1 {
>     template<typename T> void f( T* x ) {
>       // ... other stuff ...
>       delete x;
>     }
>   }

>   namespace N2 {

//>     using N1::f;
      using namespace N1; // 3.4.1/2

//>     template<> void f<int>( int* ); // A: ill-formed

>     class Test {
>       ~Test() { }
>       friend void f<>( Test* x );   // B: ill-formed?
>     };
>   }

> I strongly suspect, but don't have standardese to prove, that the friend
> declaration in line B is ill-formed. Can someone show me the text that
> allows or disallows line B?

It was, but now isn't.  Can someone explain that logic?

John

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]