Reputation:
Please read the code to know the problem :
#include <iostream>
void fun(int value)
{
//starts local class definition
class test
{
int x;
public:
test(int a) : x(a) {}
void display() const
{
std::cout << "x = " << x << std::endl;
}
};
//end of the definition
test t1(value);
t1.display();
//if we write the statement t1.x=100; here .It will give us an error
//because we can not access the private members from the enclosing function
//now what should I do if I want to access the private members of the test class from fun function
}
int main()
{
fun(5);
}
Should I make the fun function as friend for the local class(test). I was reading a book and there was said that we can achieve this by declaring the enclosing function as a friend
. Now my problem is this I don't know how to make the enclosing function as a friend of the local class. Please, someone tell me how can I do so.
Upvotes: 1
Views: 285
Reputation: 217135
Qualified call friend void ::fun(int);
is a way:
void fun(int value)
{
//starts local class definition
class test
{
friend void ::fun(int);
int x;
public:
test(int a)
{
x=a;
}
void display()
{
std::cout << "x = " << x << std::endl;
}
};
//end of the definition
test t1(value);
t1.display();
t1.x = 42;
t1.display();
}
Notice than some old version of g++ reject it.
Upvotes: 2
Reputation: 145
Note that this bug has now been fixed in GCC, and backported to versions 10 and up.
Upvotes: 0
Reputation: 238311
Should I make the fun function as friend for the local class(test)
It's unclear whether you should. It is often a good idea to avoid breaking the encapsulation that private members offer. Or conversely, if the encapsulation isn't needed, then maybe it would be simpler for the member to be public. But let's instead consider whether you could...
Standard says (quoting latest draft):
[class.friend]
If a friend declaration appears in a local class ([class.local]) and the name specified is an unqualified name, a prior declaration is looked up without considering scopes that are outside the innermost enclosing non-class scope. For a friend function declaration, if there is no prior declaration, the program is ill-formed. ...
If I interpret this legalese correctly, no unqualified name outside of the function body of fun
can be looked up. As far as I know, the declaration of fun
itself is outside of that scope. However also as far as I know, nothing should prevent you from re-declaring the function:
void fun(int value)
{
void fun(int); // (re)declaration within innermost enclosing non-class scope
class test
{
friend void fun(int); // the friend declaration
This appears to work in Clang and MSVC, but not in GCC unfortunately, which still doesn't allow access to the private member. This may be a GCC bug.
Another option would be to declare the friend with a qualified name:
class test
{
friend void ::fun(int); // qualified name
In which case the restriction above wouldn't apply. Unfortunately, GCC doesn't accept this either, and without the local re-declaration produces a diagnostic:
error: friend declaration 'void fun(int)' in local class without prior local declaration
This looks like a separate bug, which reproduces whether declaring ::fun
or any other qualified function name as friend. I found an existing bugreport: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69410
Upvotes: 2
Reputation:
First declare the function
void fun(int);
Then in class :
public:
friend void ::fun(int );
Upvotes: 0