473,811 Members | 2,783 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Friends again... (no templates :)

Hello

Consider the following code fragment

namespace N {
struct S {
void foo();
};
}

using namespace N; // 1

class C {
friend struct S; // 2
C() {}
};

void N::S::foo() {
C c; // 3 Is C's constructor accessible here???
}

According to what I can see in the standard, friend declaration at point
2 is supposed to perform name lookup for unqualified name 'S' in order
to determine whether this is the first declaration of 'S'. According to
7.3.1.2/3, the lookup goes up to the innermost enclosing namespace scope
(which happens to be the global scope in this case). According to
3.4.1/2, name 'S' introduced by a using directive at point 1 is
considered to be a member of global namespace for the purposes of
unqualified name lookup. This makes me to conclude that the friend
declaration at 2 is supposed to refer to 'N::S' instead of introducing a
new [hidden] declaration of 'struct S' into the global namespace. I.e.
the constructor of 'C' is supposed to be accessible at point 3.

Experiments show that GCC 3.3.3 accepts the code. So does MSVC++ 2005
(for what it's worth). But Comeau Online rejects it, complaining that
the constructor is inaccessible at 3. I just found out that GCC 4.1 also
refuses to compile this code for the same reason.

Did something change in the language specification recently? Something
that applies in this case?

--
Best regards,
Andrey Tarasevich
Feb 1 '07 #1
6 1477
On 2/1/07 3:06 PM, in article 12************* @news.supernews .com, "Andrey
Tarasevich" <an************ **@hotmail.comw rote:
Consider the following code fragment

namespace N {
struct S {
void foo();
};
}

using namespace N; // 1

class C {
friend struct S; // 2
C() {}
};

void N::S::foo() {
C c; // 3 Is C's constructor accessible here???
}

According to what I can see in the standard, friend declaration at point
2 is supposed to perform name lookup for unqualified name 'S' in order
to determine whether this is the first declaration of 'S'. According to
7.3.1.2/3, the lookup goes up to the innermost enclosing namespace scope
(which happens to be the global scope in this case). According to
3.4.1/2, name 'S' introduced by a using directive at point 1 is
considered to be a member of global namespace for the purposes of
unqualified name lookup. This makes me to conclude that the friend
declaration at 2 is supposed to refer to 'N::S' instead of introducing a
new [hidden] declaration of 'struct S' into the global namespace. I.e.
the constructor of 'C' is supposed to be accessible at point 3.
A using directive like the one above ("using namespace N") does not
"introduce" any names into the declarative region in which the directive
appears. Instead, a using directive merely affects how names are looked up
within that declarative region.

Since a friend declaration requires that the named friend (S in this case)
be a member of the enclosing declarative region (if the friend is to be
found there), a using directive is not enough in this case for the compiler
to find the intended friend class: N::S.

Since a using declaration does introduce a name into its enclosing region,
it is possible to fix this problem by using a using declaration instead of
using a using directive to bring the name S into the proper declarative
region. For example:

using N::S; // 1

class C
{
friend struct S; // 2
C() {}
};

Greg

Feb 2 '07 #2
Andrey Tarasevich wrote:
Hello

Consider the following code fragment

namespace N {
struct S {
void foo();
};
}

using namespace N; // 1

class C {
friend struct S; // 2
public:
C() {}
};

void N::S::foo() {
C c; // 3 Is C's constructor accessible here???
}
Comeau should now be able to compile it.

Regards,
Sumit.
Feb 2 '07 #3
Sumit Rajan wrote:
Andrey Tarasevich wrote:
>Hello

Consider the following code fragment

namespace N {
struct S {
void foo();
};
}

using namespace N; // 1

class C {
friend struct S; // 2

public:
> C() {}
};

void N::S::foo() {
C c; // 3 Is C's constructor accessible here???
}

Comeau should now be able to compile it.

Oops! Should've paid more attention. Please disregard my previous post.

Sumit.
Feb 2 '07 #4
Greg Herlihy wrote:
>
>Consider the following code fragment

namespace N {
struct S {
void foo();
};
}

using namespace N; // 1

class C {
friend struct S; // 2
C() {}
};

void N::S::foo() {
C c; // 3 Is C's constructor accessible here???
}

According to what I can see in the standard, friend declaration at point
2 is supposed to perform name lookup for unqualified name 'S' in order
to determine whether this is the first declaration of 'S'. According to
7.3.1.2/3, the lookup goes up to the innermost enclosing namespace scope
(which happens to be the global scope in this case). According to
3.4.1/2, name 'S' introduced by a using directive at point 1 is
considered to be a member of global namespace for the purposes of
unqualified name lookup. This makes me to conclude that the friend
declaration at 2 is supposed to refer to 'N::S' instead of introducing a
new [hidden] declaration of 'struct S' into the global namespace. I.e.
the constructor of 'C' is supposed to be accessible at point 3.

A using directive like the one above ("using namespace N") does not
"introduce" any names into the declarative region in which the directive
appears.
Yes, it does "virtually" introduce the names into the region
("virtually" here means that the names are introduced for the purpose of
name lookup only). That is exactly what 3.4.1/2 says:

"For the purpose of of the unqualified name lookup rules described in
3.4.1, the declarations from the namespace nominated by the
'using-directive' are considered members of that enclosing namespace."
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^
Instead, a using directive merely affects how names are looked up
within that declarative region.
Well, that is exactly _how_ in affects the lookup process. By
introducing the names into the region _as_ _members_ (for the purposes
of unqualified name lookup only).
Since a friend declaration requires that the named friend (S in this case)
be a member of the enclosing declarative region (if the friend is to be
found there), a using directive is not enough in this case for the compiler
to find the intended friend class: N::S.
The standard does not agree with you on that. Once again, it literally
says that in the above example for the purposes of unqualified name
lookup name 'S' (standing for 'N::S') is considered a member of global
namespace.
Since a using declaration does introduce a name into its enclosing region,
it is possible to fix this problem by using a using declaration instead of
using a using directive to bring the name S into the proper declarative
region. For example:

using N::S; // 1

class C
{
friend struct S; // 2
C() {}
};
This will cause at least Comeau Online to issue a different error - at
point 2 it will say that name 'S' has already been declared in this
scope. It is the same problem as in

namespace N { struct S {}; }

using N::S;
struct S {}; // ERROR: 'S' has already been declared

Apparently, in your modified example Comeau still refuses to link friend
declaration to 'N::S'. I might look into that separately later, but at
this time I'm primarily interested in the original version with using
directive.

--
Best regards,
Andrey Tarasevich

Feb 2 '07 #5
Andrey Tarasevich wrote:
...
Did something change in the language specification recently? Something
that applies in this case?
...
OK, it looks like it all comes from here

http://www.open-std.org/jtc1/sc22/wg...ctive.html#138
http://www.open-std.org/jtc1/sc22/wg...000/n1229.html

It all still appears to be in the drafting stage, but according to the
recommendations section in 'n1229' using directives should not be
considered by name lookup performed for friend declarations. In other
words, Comeau Online and GCC 4.1 do indeed violate the requirements of
the current language specification by implementing on of the possible
future changes in it (a bit prematurely, I'd say).

--
Best regards,
Andrey Tarasevich

Feb 2 '07 #6
Andrey Tarasevich wrote:
...
It looks like the situation with correct support of "friends" is pretty
grim even when it comes to simpler cases. In the following code

struct B { void foo(); };

namespace X {
class A {
A() {}
friend struct B; // refers to X::B, not to ::B
};

struct B {
void foo();
};
}

void X::B::foo() {
X::A a; // OK
}

void B::foo() {
X::A a; // ERROR
}

compilers are supposed to accept the 'OK' line and reject the 'ERROR'
one. In practice so far I only found that Comeau Online and Forte
Developer 7 C++ 5.4 behave properly. MS C++ compilers (including 2005),
GCC 3 get it wrong. And that despite the fact that the standard even has
a specific example dedicated to this situation in 7.3.1.2/3...

--
Best regards,
Andrey Tarasevich
Feb 2 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
3190
by: Gianni Mariani | last post by:
I have 2 distinct template classes which co-operate, hence are friends. However, I can't seem to figure out what syntax to use to make this work. What is the right(tm) way to write a friend class here ? Here is the code: template <typename A> class Y;
6
1528
by: Roger Leigh | last post by:
I've written a fixed-precision class, "numeric". This stores the number of decimal places as a template parameter. I've overloaded all of the normal numerical operators (an example): template<unsigned short Dp> class numeric { public: // Round mode and precision are not assigned.
10
2211
by: william xuuu | last post by:
Actually, I also got linker errors with template functions and template classes. And I avoided both of them successfully, by pouring foo.cpp into foo.h, according to the C++ FAQ. (http://www.parashift.com/c++-faq-lite/containers-and-templates.html) And then, I pre-declared each template friend function above the definition of template class. But I still get template friends linker error. My compiler is gcc 3.3.3. Any hints? Thanks,
11
2765
by: Steven T. Hatton | last post by:
In the past there have been lengthy discussiions regarding the role of header files in C++. People have been very adamat about header files serving as in interface to the implementation. I do understand the objective. This example may represent an interface in need of a bit of refactoring, but it goes to demonstrate the basic idea as I understand it. http://developer.kde.org/documentation/library/cvs-api/kdevelop/html/ast_8h-source.html...
7
1337
by: fabio de francesco | last post by:
Hello, I'm just joking with the Subject, but I really don't know how to make a synthesis of two questions about some code I'm trying to write. In the following I post this little code, with "..." meaning what I think can be omitted for brevity. // file database.h
1
1338
by: Tom McCallum | last post by:
Hi, Can someone please tell me the correct syntax (if its possible of course) to specify an output stream operator for a templated class so that I dont need to write the same function for all the derived classes from the template. I have a sample of what it thought it might look like below. ==BEGIN CODE SNIPPET===
11
2607
by: Micha | last post by:
Hello there, I think I've run into some classic c++ pitfall and maybe some of you guys can help me out. For my project I will need to use matrices and vectors and so I decided to implement them by myself. I know there are already tons of vector and matrix implementations, but I wanted to have one taylored for my needs and without debugging someones else code. Also is's become somewhat personal meanwhile ;-).
3
1726
by: shaun roe | last post by:
Hello, I am working in a framework with certain restrictions; in particular I have a 'data' class with getter and setter methods, and a some 'filling' classes which know how to insert the data to the data class (they match various sources such as a text file or a database, and then fill the data). The filling methods use the 'setter' methods of the data class, but then I want to present the data class to the outside world (i.e. other
9
1706
by: Klaas Vantournhout | last post by:
Hi all, I have a question about friends functions of a template class. To make it simple, I would like to do something like this. Assume that I have a class foo with template T template<Tclass foo
0
9734
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9607
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10137
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9211
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7673
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5561
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4346
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3874
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3026
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.