Reputation: 1968
I am debugging an application which interacts with third party library whose code is not available only header and .so are available. Now I can load it into debugger and check variable values of private member of class declared in third party library but since number of objects are huge, I want to create some mechanism to print it on console which I can analyse later. I came up with something like this
ThirdPartyHeader
class A
{
private:
int i;
};
I have not included extra details in above class
Debugprinter.cpp
#include <thirdpartheaders>
template <typename T> class debugprinter
{
friend class T;
public :
void printonconsole()
{
T a;
std::cout << std::endl << a.i << std::endl;
return;
}
}
Now I tried to compile above this but it seems that I can't declare undefined type T as friend to my template class and get this error
Error: i is not accessible from x::acc()
Now I can resolve this problem by creating non template debugprinter but just out of curiosity is there a way I can create a template class which would be friend to it's input type parameter?
Thanks
Upvotes: 1
Views: 1483
Reputation: 208416
The first thing is that as others mentioned friendship is not symmetric and you are attempting the wrong direction (granting A
access to debugprinter<A>
. That being said, and just for the sake of people searching through questions:
In the old version of the standard (C++03) it was impossible to directly declare a template argument as a friend. That restriction was lifted in C++11, although it requires a slightly different syntax:
template <typename T>
class test {
friend T; // note, not 'friend class T'!!!
};
Still, in C++03 you could achieve the same behavior by using one extra level of indirection. You cannot befriend a template argument, but you can befriend a dependent type, and by using an identity
meta-function you could achieve what you wanted:
template <typename T>
struct identity {
typedef T type;
};
template <typename T>
class test {
friend class identity<T>::type;
};
Upvotes: 3
Reputation: 13471
It wouldn't help to declare A
as a friend of debugprinter<A>
. The friend
relation is not symmetric. The relation is only one-way. You would need debugprinter<A>
to be a friend of A
if you want to access private members of A
. For that you need to modify the class A
itself.
It is like with real-world friendship. You can't force somebody else to be your friend. You can only yourself behave friendly to others.
Upvotes: 5
Reputation: 76438
You can declare T
as a friend, but it won't do you any good. What's needed is a way for your template to get at the private data in T
, and that goes the other way around: T
would have to declare your template as a friend. Decisions about friendship are made by the class that's offering friendship; it can't be demanded from another class. Without a friend declaration, there's no legitimate way to get at a class's private parts from outside; that's what private means.
Upvotes: 3