Topic: template function access of private members.
Author: einwegadresse@gmx.de (Immanuel Scholz)
Date: Thu, 5 Jun 2003 18:01:42 +0000 (UTC) Raw View
Hi,
Assuming the following code:
template <class C> void glob(C param) { param.foo(); }
class outer {
struct inner { void foo() {} };
public:
struct inner2 {
void bar() {
glob(inner());
}
};
};
int main() {
outer::inner2 o; o.bar();
return 0;
}
On GCC it compiles, on CL.EXE it does not compile, complaining about
access rights on the line "glob(inner());"
error C2248: 'inner::inner' : cannot access public member declared in
class 'outer::inner'
I assume what CL.EXE means, is that the resolved global function glob
cannot access the private struct outer::inner.
Who is right? GCC or CL.EXE? And how do I solve the problem in CL.EXE
if I want to give the access rights to glob?
Insert "friend void glob(inner param);" into the declaration of
outer::inner does not help...
Immanuel Scholz
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: v.Abazarov@attAbi.com ("Victor Bazarov")
Date: Thu, 5 Jun 2003 22:15:42 +0000 (UTC) Raw View
"Immanuel Scholz" <einwegadresse@gmx.de> wrote...
> Assuming the following code:
>
> template <class C> void glob(C param) { param.foo(); }
> class outer {
> struct inner { void foo() {} };
> public:
> struct inner2 {
> void bar() {
> glob(inner());
Actually, the error should be reported here. 'inner2' has
no access to 'inner', and therefore has no access to any
of its members (implicit constructor included).
Change the code slightly and you will see that the template
is not the problem:
class outer
{
struct inner { void foo() {} };
public:
static void foo(const inner&) {}
struct inner2 {
void bar() {
outer::foo(inner());
}
};
};
int main() {
outer::inner2 o; o.bar();
return 0;
}
> }
> };
> };
> int main() {
> outer::inner2 o; o.bar();
> return 0;
> }
>
> On GCC it compiles, on CL.EXE it does not compile, complaining about
> access rights on the line "glob(inner());"
>
> error C2248: 'inner::inner' : cannot access public member declared in
> class 'outer::inner'
>
>
> I assume what CL.EXE means, is that the resolved global function glob
> cannot access the private struct outer::inner.
No. 'inner2::bar' has no access to 'inner' or its members.
>
> Who is right? GCC or CL.EXE?
CL.EXE (Visual C++ I presume) is correct.
> And how do I solve the problem in CL.EXE
> if I want to give the access rights to glob?
You have to grant 'inner2' access to 'inner' by declaring it
a friend of 'outer', for example.
> Insert "friend void glob(inner param);" into the declaration of
> outer::inner does not help...
And it shouldn't. Insert 'friend struct inner2;' into the
declaration of 'outer'.
Victor
--
Please remove capital A's from my address when replying by mail
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: bop2@telia.com ("Bo Persson")
Date: Thu, 5 Jun 2003 22:15:59 +0000 (UTC) Raw View
"Immanuel Scholz" <einwegadresse@gmx.de> skrev i meddelandet
news:7df0cdd.0306050452.6b45af17@posting.google.com...
> Hi,
>
> Assuming the following code:
>
> template <class C> void glob(C param) { param.foo(); }
> class outer {
> struct inner { void foo() {} };
> public:
> struct inner2 {
> void bar() {
> glob(inner());
> }
> };
> };
> int main() {
> outer::inner2 o; o.bar();
> return 0;
> }
>
> On GCC it compiles, on CL.EXE it does not compile, complaining about
> access rights on the line "glob(inner());"
>
> error C2248: 'inner::inner' : cannot access public member declared
in
> class 'outer::inner'
>
>
> I assume what CL.EXE means, is that the resolved global function
glob
> cannot access the private struct outer::inner.
>
> Who is right? GCC or CL.EXE?
They are sort of both right. :-)
In this case CL implements the letter of the standard, and GCC the
intent. There is a defect report clarifying this issue:
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_defects.html#45
Bo Persson
bop@telia.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (LLeweLLyn)
Date: Fri, 6 Jun 2003 21:03:07 +0000 (UTC) Raw View
v.Abazarov@attAbi.com ("Victor Bazarov") writes:
> "Immanuel Scholz" <einwegadresse@gmx.de> wrote...
>> Assuming the following code:
>>
>> template <class C> void glob(C param) { param.foo(); }
>> class outer {
>> struct inner { void foo() {} };
>> public:
>> struct inner2 {
>> void bar() {
>> glob(inner());
>
> Actually, the error should be reported here. 'inner2' has
> no access to 'inner', and therefore has no access to any
> of its members (implicit constructor included).
[snip]
>> On GCC it compiles, on CL.EXE it does not compile, complaining about
>> access rights on the line "glob(inner());"
>>
>> error C2248: 'inner::inner' : cannot access public member declared in
>> class 'outer::inner'
>>
>>
>> I assume what CL.EXE means, is that the resolved global function glob
>> cannot access the private struct outer::inner.
>
> No. 'inner2::bar' has no access to 'inner' or its members.
>
>>
>> Who is right? GCC or CL.EXE?
>
> CL.EXE (Visual C++ I presume) is correct.
[snip]
What about the proposed resolution of DR#45?
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_defects.html#45
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: Fri, 6 Jun 2003 21:03:35 +0000 (UTC) Raw View
On Thu, 5 Jun 2003 18:01:42 +0000 (UTC), einwegadresse@gmx.de (Immanuel
Scholz) wrote:
> template <class C> void glob(C param) { param.foo(); }
> class outer {
> struct inner { void foo() {} };
> public:
> struct inner2 {
> void bar() {
> glob(inner());
Inner2 has no special access to outer's privates.
The workaround is not valid, but is accepted by many compilers.
public:
struct inner2; // without this the friend would be a global.
friend struct inner2;
struct inner2 {
...
John
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]