Topic: Selective access to members of a class


Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/08/11
Raw View
David Vandevoorde <daveed@vandevoorde.com> writes:

> I think the above code has two errors:
>
> 1) Only member functions, static data members and friends have
>    access to private members of a class (see [class.access]/1).
>    A typedef is none of these: the &A::b above therefore
>    violates access-rules.

Are you saying that:

class Foo {
    class private_secret { };
public:
    typedef private_secret iterator;
};

is ill-formed ? I can't believe that it's the intent of
the commitee; I guess it's an oversight.

--

Valentin Bonnard
mailto:bonnardv@pratique.fr
http://www.pratique.fr/~bonnardv (Informations sur le C++ en Francais)
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: kuehl@horn.informatik.uni-konstanz.de (Dietmar Kuehl)
Date: 1997/08/11
Raw View
Hi,
David Vandevoorde (daveed@vandevoorde.com) wrote:
: Dietmar Kuehl wrote:
: [ I'm cross-posting this article to comp.std.c++,
:   where it may be of interest ...]

: >   template <class Str, class T, T Str::*member, class Friend>
: >   class SelectiveFriend
: >   {
: >     friend class Friend;
: >     static T       &access(Str       &str) { return str.*member; }
: >     static T const &access(Str const &str) { return str.*member; }
: >     static T       &access(Str       *str) { return str->*member; }
: >     static T const &access(Str const *str) { return str->*member; }
: >   };
: >
: > This is basically an accessor object which can be used to grant access
: > to an arbitrary member of an arbitrary class to some arbitrary class.
: > This class is used like this:
: >
: >   class B;
: >   class A
: >   {
: >     T1 a;
: >     T2 b;
: >     T3 c;
: >
: >   public:
: >     typedef class SelectiveFriend<A, T2, &A::b, B> b_access;
: >     friend b_access;
: >     // ...
: >   };

: I think the above code has two errors:

: 1) Only member functions, static data members and friends have
:    access to private members of a class (see [class.access]/1).
:    A typedef is none of these: the &A::b above therefore
:    violates access-rules.

Class 'A' has obviously access to 'A's members. Thus, '&A::b' is
definitely legal in the code above: A class can form a pointer to all
of its own members like eg. the member 'b' of 'A' above. I can't see
why this should be an access violation.

: 2) The friend syntax requires an elaborated-type-specifier;
:    a typedef-name won't do. There is a workaround:
:  friend class SelectiveFriend<A, T2, &A::b, B>;

I can accept this one: I always thought that typedef'ed types and the
types can be used exactly identically. Thus, I assumed that I can make
a typedef'ed typed a friend. Like you observed, there is a simple
work-around although I would really like if this would not
necessary...

: Unless I'm mistaken, you have discovered some bugs in KCC
: and conforming compilers should diagnose this code.

I think one of the errors is not really an error and the typedef thing
would be desirable to work with any standard conforming compiler.
However, I haven't checked whether it is indeed not supported by
stanard conforming compilers. I should do this since to file a
corresponding bug report if necessary: the KCC folks are extremely
responsive to bug reports.
--
<mailto:dietmar.kuehl@uni-konstanz.de>
<http://www.informatik.uni-konstanz.de/~kuehl/>
I am a realistic optimist - that's why I appear to be slightly pessimistic
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: David Vandevoorde <daveed@vandevoorde.com>
Date: 1997/08/13
Raw View
Dietmar Kuehl wrote:
>
> Hi,
> David Vandevoorde (daveed@vandevoorde.com) wrote:
> : Dietmar Kuehl wrote:
> : [ I'm cross-posting this article to comp.std.c++,
> :   where it may be of interest ...]
>
> : >   template <class Str, class T, T Str::*member, class Friend>
> : >   class SelectiveFriend
> : >   {
> : >     friend class Friend;
> : >     static T       &access(Str       &str) { return str.*member; }
> : >     static T const &access(Str const &str) { return str.*member; }
> : >     static T       &access(Str       *str) { return str->*member; }
> : >     static T const &access(Str const *str) { return str->*member; }
> : >   };
> : >
> : > This is basically an accessor object which can be used to grant access
> : > to an arbitrary member of an arbitrary class to some arbitrary class.
> : > This class is used like this:
> : >
> : >   class B;
> : >   class A
> : >   {
> : >     T1 a;
> : >     T2 b;
> : >     T3 c;
> : >
> : >   public:
> : >     typedef class SelectiveFriend<A, T2, &A::b, B> b_access;
> : >     friend b_access;
> : >     // ...
> : >   };
>
> : I think the above code has two errors:
>
> : 1) Only member functions, static data members and friends have
> :    access to private members of a class (see [class.access]/1).
> :    A typedef is none of these: the &A::b above therefore
> :    violates access-rules.
>
> Class 'A' has obviously access to 'A's members.

As far as CD2 is concerned, I think it's not so `obvious';
[class.access]/1 says:

   A member of a class can be

     --private; that is, its name can be used only by member
       functions, static data members, and friends of the
       class in which it is declared.

> Thus, '&A::b' is definitely legal in the code above:
> A class can form a pointer to all of its own members like
> eg. the member 'b' of 'A' above. I can't see why this should
> be an access violation.

See above. However, I concur with Valentin Bonnard that this
could be an oversight (or that I am overlooking another item
in CD-2).

 Daveed
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: David Vandevoorde <daveed@vandevoorde.com>
Date: 1997/08/07
Raw View
Dietmar Kuehl wrote:
[ I'm cross-posting this article to comp.std.c++,
  where it may be of interest ...]

>   template <class Str, class T, T Str::*member, class Friend>
>   class SelectiveFriend
>   {
>     friend class Friend;
>     static T       &access(Str       &str) { return str.*member; }
>     static T const &access(Str const &str) { return str.*member; }
>     static T       &access(Str       *str) { return str->*member; }
>     static T const &access(Str const *str) { return str->*member; }
>   };
>
> This is basically an accessor object which can be used to grant access
> to an arbitrary member of an arbitrary class to some arbitrary class.
> This class is used like this:
>
>   class B;
>   class A
>   {
>     T1 a;
>     T2 b;
>     T3 c;
>
>   public:
>     typedef class SelectiveFriend<A, T2, &A::b, B> b_access;
>     friend b_access;
>     // ...
>   };

I think the above code has two errors:

1) Only member functions, static data members and friends have
   access to private members of a class (see [class.access]/1).
   A typedef is none of these: the &A::b above therefore
   violates access-rules.

2) The friend syntax requires an elaborated-type-specifier;
   a typedef-name won't do. There is a workaround:
 friend class SelectiveFriend<A, T2, &A::b, B>;

[...]
> Unfortunately, this technique is not yet supported by man compilers...
> (KCC does compile code like this but other compilers I have available
> do not). However, every C++ compiler conforming to the standard will
> be able to compile this code.

Unless I'm mistaken, you have discovered some bugs in KCC
and conforming compilers should diagnose this code.

 Daveed
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]