Topic: two suggested new language features related to class data members


Author: Walt <wkaras@yahoo.com>
Date: Tue, 31 Mar 2009 17:08:31 CST
Raw View
On Mar 26, 11:42 pm, W Karas <wka...@yahoo.com> wrote:
...
> 2)
>
> Allow declarations of the form:
>
> class X.Y ... ;
>
> to indicate that class Y can only be used as the type of data members
> of class X.  If Y is member of class X, X can be omitted:
>
> class X
>    {
>    ...
>    class .Y ... ;
>    ...
>    };
....

An alternate to using this suggested feature would be to define the
class data member with an anonymous class.  The only potential problem
with this alternative is that anonymous classes are currently not
permitted to have base classes.


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: W Karas <wkaras@yahoo.com>
Date: Thu, 26 Mar 2009 21:42:37 CST
Raw View
1)

New implicitly-defined overloads of the - operator to make it possible
to get an object address from a data member address.  Example usage:

C *containing_C = p - &(C::m);

where C is the name of a class, m a member of C, and p a pointer whose
type is the same as the type of m .  p presumably points to the member
m of some instance of C, and after the execution of this statement,
containing_C will point to the instance of C containing m .

If p does not point to a member of an instance of C, the results would
be undefined.  Clearly this is somewhat dangerous.  So (following the
"make danger ugly" philosophy that motivated the syntax of  the new
casts) perhaps, instead of overloading -, an implicitly defined
templeted function should be introduced:

namespace std
{
template <class C, class M>
C * __containing(const volatile C *, const volatile C::*M);
}

changing the above example to:

C *containing_C = std::__containing(p, &(C::m));

2)

Allow declarations of the form:

class X.Y ... ;

to indicate that class Y can only be used as the type of data members
of class X.  If Y is member of class X, X can be omitted:

class X
   {
   ...
   class .Y ... ;
   ...
   };

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Arne Mertz <news@arne-mertz.de>
Date: Fri, 27 Mar 2009 15:26:03 CST
Raw View
W Karas schrieb:

> 2)
>
> Allow declarations of the form:
>
> class X.Y ... ;
>
> to indicate that class Y can only be used as the type of data members
> of class X.  If Y is member of class X, X can be omitted:
>
> class X
>    {
>    ...
>    class .Y ... ;
>    ...
>    };
>

In what way would you use this?
You cannot use any instance of .Y outside of X, not even as a
parameter to one of X's methods, because you would have to construct
an .Y outside of X, or bin a .Y& to another .Y in another X. Both
would not be permittet if you take "only be used as a type of data
member of X" seriously.
So if you can't use it outide X, there is no point to have the type
visible outside of X - you probably do not want to compare data
members directly or have pointer-to-members to them, because in most
or nearly all cases the datamembers are private anyway. But for
types that are not visible outside of X there is no need to have a
new type of declarations - just use private member classes.
Did I miss something that you could do with your "internal" class
that you can not with private (or protected) member classes?

greets
Arne

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: wasti.redl@gmx.net
Date: Fri, 27 Mar 2009 17:59:27 CST
Raw View
On Mar 27, 4:42 am, W Karas <wka...@yahoo.com> wrote:
> 1)
>
> New implicitly-defined overloads of the - operator to make it possible
> to get an object address from a data member address.  Example usage:
>
> C *containing_C = p - &(C::m);
>
> where C is the name of a class, m a member of C, and p a pointer whose
> type is the same as the type of m .  p presumably points to the member
> m of some instance of C, and after the execution of this statement,
> containing_C will point to the instance of C containing m .

Good heavens, what for? If you know m by name, you can achieve this
with offsetof:
C *containing_C = reinterpret_cast<C*>(reinterpret_cast<char*>(p) -
offsetof(C, m));
This is undefined if C is not a POD, and implementation-defined in
general due to the reinterpret_casts, but it should work on the
popular platforms.
If you don't know m by name, but only by pointer, ... what weird
situation is it that you have a, say, int* and an int C::*, and you
know that the int* points into C but not to which member? Sounds
highly contrieved to me. Perhaps you should rethink the design that
inspired this suggestion.

> 2)
>
> Allow declarations of the form:
>
> class X.Y ... ;
>
> to indicate that class Y can only be used as the type of data members
> of class X.

That's what private member classes are for.

Sebastian


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Walt <wkaras@yahoo.com>
Date: Sun, 29 Mar 2009 00:18:46 CST
Raw View
On Mar 27, 5:26 pm, Arne Mertz <n...@arne-mertz.de> wrote:
> W Karas schrieb:
>
>
>
> > 2)
>
> > Allow declarations of the form:
>
> > class X.Y ... ;
>
> > to indicate that class Y can only be used as the type of data members
> > of class X.  If Y is member of class X, X can be omitted:
>
> > class X
> >    {
> >    ...
> >    class .Y ... ;
> >    ...
> >    };
>
> In what way would you use this?
> You cannot use any instance of .Y outside of X, not even as a
> parameter to one of X's methods, because you would have to construct
> an .Y outside of X, or bin a .Y& to another .Y in another X. Both
> would not be permittet if you take "only be used as a type of data
> member of X" seriously.
> So if you can't use it outide X, there is no point to have the type
> visible outside of X - you probably do not want to compare data
> members directly or have pointer-to-members to them, because in most
> or nearly all cases the datamembers are private anyway. But for
> types that are not visible outside of X there is no need to have a
> new type of declarations - just use private member classes.
> Did I miss something that you could do with your "internal" class
> that you can not with private (or protected) member classes?

The two suggestions are related.  If y is a (actually the) data member
of X of type Y, and the expression (this - &(X::y)) is used to get the
address of the containing instance of X, then this provides the reason
for defining Y in this manner.  The idea is that, if X is a complex
class, you may want to break pieces of the complexity into other
classes like Y, but have Y's member functions be able to access
members of both the Y instance and the X instance that the Y instance
is in.

Sorry, I should have mentioned this in the OP.


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]