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 ]