/** module.h */
#pragma once
class A {
friend void helpers::logValue(const A &);
int _val;
public:
A() {}
};
namespace helpers {
static void logValue(const A &a) {
std::cout << a._val; // <== ERROR: '_val' is not accessible
}
}
How do I declare the friend function in another namespace?
To come up with a solution, it is necessary to work backward.
We want this to work with _val a private member of class A.
namespace helpers {
static void logValue(const A &a) {
std::cout << a._val;
}
}
Step 1 For the function definition above to work there must be a preceding definition of class A visible the compiler, and that class definition must specify that helpers::logValue() (with the appropriate signature i.e. return type and arguments) is a friend. So before the definition above of helpers::logValue() we must place;
class A {
friend void helpers::logValue(const A &);
int _val;
};
Step 2 For that friend declaration in Step 1 to be valid, the compiler must know about helpers::logValue(). That requires a declarative region of namespace helpers visible to the compiler that declares a function logValue() with the same signature, and that must be before the definition of A. So, before our definition of class A, we must do something like;
namespace helpers{
static void logValue(const A &a);
}
Step 3 The compiler will choke on this declaration of helpers::logValue() if there is no declaration of class A visible. We already have a class definition (created in Step 1), so we cannot create another one (that would break the one-definition rule). But we can add a declaration before the code from Step 2.
class A;
Putting those steps together, we put the code from the steps together in reverse order (i.e. put the code from Step 3 first, follow up with the code from Step 3, etc). We then get
// Step 3
class A;
// Below Step 3 comes code from Step 2
namespace helpers{
static void logValue(const A &a); // works since A is declared
}
// Below Step 2 comes code from Step 1
class A {
friend void helpers::logValue(const A &); // works since helpers::logValue() is declared
int _val;
};
// And now we come to the function definition we want to have work
namespace helpers {
static void logValue(const A &a) {
std::cout << a._val;
}
}
One possible way of solving this is as shown below:
class A;//forward declaration for class A
namespace helpers{
static void logValue(const A &a); //declaration
}
///////////////////////////////////////////
class A {
friend void helpers::logValue(const A &);
int _val;
};
namespace helpers {
static void logValue(const A &a) {
std::cout << a._val; // works now
}
}
The output of the above program can be seen here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With