Templated friend function can't access private members?

M

mrstephengross

Hi folks... I've been sifting through archived postings on this, but
haven't quite found an answer yet. I've got a templated stand-alone
function:

template<typename T> void access(const T & t) { ; }

And a class 'Foo':

struct Foo {
friend void access(const Foo & f);
private:
int x;
};

As you can see, Foo is friended to the function 'access'. One more
thing to do: specialize access() for Foo:

template<> void access(const Foo & f) { f.x = 9; }

So access() should be able to work, right? Because access() has been
friended properly to Foo?

The following main() code, however, won't compile. The compiler
complains that 'x' is private:

int main() {
Foo f;
access(f);
}

Did I declare the friend function incorrectly? Or is this simply not
possible?

Thanks in advance,
--Steve ([email protected])
 
R

Rolf Magnus

mrstephengross said:
Hi folks... I've been sifting through archived postings on this, but
haven't quite found an answer yet. I've got a templated stand-alone
function:

template<typename T> void access(const T & t) { ; }

And a class 'Foo':

struct Foo {
friend void access(const Foo & f);
private:
int x;
};

As you can see, Foo is friended to the function 'access'.

Yes, to a non-templated overload of it.
One more thing to do: specialize access() for Foo:

template<> void access(const Foo & f) { f.x = 9; }

So access() should be able to work, right? Because access() has been
friended properly to Foo?

Not if you mean the template specialization.
The following main() code, however, won't compile. The compiler
complains that 'x' is private:

int main() {
Foo f;
access(f);
}

Did I declare the friend function incorrectly? Or is this simply not
possible?

Try:

friend void access<>(const Foo & f);
 
M

mrstephengross

Ok, the addition of the "<>" got it working. My next problem is
namespaces, though. I stick Foo in a namespace ("NS"), and it compiles;
the linker, however, complains that access<> is multiply defined:

================================================
template<typename T> void access(const T & t) { ; }
namespace NS {
struct Foo {
friend void access<>(const NS::Foo & f);
private:
int x;
};
} // End namespace

template<> void access(const NS::Foo & f) { f.x = 9; }

int main() { NS::Foo f; access(f); }
================================================

Am I maybe forgetting 'inline' tags? Is there some fundamental issue
with templates & namespaces?

Thanks again,
--Steve
 
L

loic-dev

mrstephengross said:
Ok, the addition of the "<>" got it working. My next problem is
namespaces, though. I stick Foo in a namespace ("NS"), and it compiles;
the linker, however, complains that access<> is multiply defined:

================================================
template<typename T> void access(const T & t) { ; }
namespace NS {
struct Foo {
friend void access<>(const NS::Foo & f);
private:
int x;
};
} // End namespace

template<> void access(const NS::Foo & f) { f.x = 9; }

int main() { NS::Foo f; access(f); }
================================================

Am I maybe forgetting 'inline' tags? Is there some fundamental issue
with templates & namespaces?

I am surprised that this code can be compiled, as you pass a reference
to a const object in access(). Hence, the compiler should complain that
you try to access 'x' which is read-only... Or am I missing something?

Furthermore, note that the code above with the const qualifier removed
compiles fine with gcc 4.1.0

Cheers,
Loic.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top