2 suggested new features for C++

W

W Karas

1)

Support the idiom:

p - static_cast<C::*M>(p)

C is a class.
M is a data member of C (not a type).
The value of p must implicitly convert to the type of M.
If the value of p (after conversion) is the address of
the member M of some instance of C, the result
of the "expression" has type C * and is the address of
the instance of C. Otherwise, the result is undefined.

This idiom could be supported directly, or by
allowing C::*M as a new sort of pointer, that
would only have default and copy constructors,
assignment. Otherwise only usable in this
weird new overload of -.

2)

Allow

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 .Y ... ;
 
J

Joe Greer

1)

Support the idiom:

Ummm, how can this be an idiom if it's new?
p - static_cast<C::*M>(p)

C is a class.
M is a data member of C (not a type).
The value of p must implicitly convert to the type of M.
If the value of p (after conversion) is the address of
the member M of some instance of C, the result
of the "expression" has type C * and is the address of
the instance of C. Otherwise, the result is undefined.

This idiom could be supported directly, or by
allowing C::*M as a new sort of pointer, that
would only have default and copy constructors,
assignment. Otherwise only usable in this
weird new overload of -.

What problem does this address?
2)

Allow

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 .Y ... ;

How is this different than:

class X
{
class Y
{
};

Y y;
};

Class Y can only be used by data members of class X.

joe
 
W

W Karas

W said:

Can you perhaps explain what problems those solve (that can't be solved
now by any other means)? Thanks!

1)

The rational is the same as for having the
capability to get the address of a derived
class instance from the address of the
base class instance within the derived
class instance.

2)

Suppose you have in a class where one
member is an array and another
this is an intrusive linked list
container for elements of the array.
Suppose that the linked list uses
array indexes as links instead of
pointers. The implementation of
the class for the container would
be dependent on the instance being
in the class with the array. This
language feature would allow this
requirement to be express and enforced
by the compiler.
 
W

W Karas

Ummm, how can this be an idiom if it's new?








What problem does this address?






How is this different than:

class X
{
class Y
{
};

Y y;

};

Class Y can only be used by data members of class X.

(I need to amend my original proposal to say that
Y can only be used for non-static data members of X.)

In your example, this would also be possible:

void X::foo(void) { Y y; ... }

#2 and #1 are related. The idea is that member functions
of Y should know it's safe to get the address of X
from the "this" pointer (to Y).
 
W

W Karas

1)

Support the idiom:

p - static_cast<C::*M>(p)

C is a class.
M is a data member of C (not a type).
The value of p must implicitly convert to the type of M.
If the value of p (after conversion) is the address of
the member M of some instance of C, the result
of the "expression" has type C * and is the address of
the instance of C. Otherwise, the result is undefined.

This idiom could be supported directly, or by
allowing C::*M as a new sort of pointer, that
would only have default and copy constructors,
assignment. Otherwise only usable in this
weird new overload of -.

Actually a better idiom would be:

static_cast<C::*M>(p) - &(C::M)

yields the address (with type C *) of
the containing instance of C.
 
W

W Karas

Actually a better idiom would be:

static_cast<C::*M>(p) - &(C::M)

yields the address (with type C *) of
the containing instance of C.

Another possibillity would be to simply
add a new overload of - :

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

Or, to appropriately scare the code
maintainer, the overloaded
- here could return a instance of the
appropriate instantiation of:

namespace std
{
template<class C>
struct CONTAINING {
C *containing; };
}

changing the above to

C* containing_C =
(p - &(C::M)).containing;
 
W

W Karas

Another possibillity would be to simply
add a new overload of - :

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

Or, to appropriately scare the code
maintainer, the overloaded
- here could return a instance of the
appropriate instantiation of:

namespace std
{
template<class C>
struct CONTAINING {
C *containing; };

}

changing the above to

C* containing_C =
(p - &(C::M)).containing;

There is, of course, a solution to this problem
using reinterpret_cast<char *> . The de facto
portability of this solution is very high, even
though the Standard does not guarantee the
portability of it. Is the fact that this de
facto solution exists a significant reason
why the language has not been changed to
address the issue?
 
J

Juha Nieminen

James said:
Well, my first wish would be that compilers would actually
implement the features we've got (e.g. like export).

Not to talk about the features of the upcoming standard. I'm really
drooling over rvalue references...
 
G

Gennaro Prota

James said:
Well, my first wish would be that compilers would actually
implement the features we've got (e.g. like export).

I think I gave up hoping for export in compilers not based on the EDG
front-end when H. Sutter presented his paper "Why We Can't Afford Export"

<http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf>

about five years ago. The minutes of the following meeting

<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1459.html>

show that pretty much nobody in the committee took it into much
consideration (see the straw poll results) but it seemed to generate
quite an outcry in the world outside. It was IMHO a "Why we
--Microsoft-- don't want to tackle export" which turned into "Why
top-most experts like Herb Sutter say that if I think I'm capable to
implement export than I haven't understood it" for every other
implementor.

And, alas, note that *even* most of the EDG-based compilers come with
export disabled.
 
J

Juha Nieminen

Gennaro said:
I think I gave up hoping for export in compilers not based on the EDG
front-end when H. Sutter presented his paper "Why We Can't Afford Export"

If I'm not completely mistaken, the latest gcc does support export
templates.
 
L

Lionel B

If I'm not completely mistaken, the latest gcc does support export
templates.

I think you may be mistaken... where did you see that? My 4.3.1 (current
stable) doesn't and the documentation under "Current development"
(http://gcc.gnu.org/onlinedocs/) still says "GCC implements the majority
of C++98 (export is a notable exception)...".
 
J

Juha Nieminen

Lionel said:
I think you may be mistaken... where did you see that? My 4.3.1 (current
stable) doesn't and the documentation under "Current development"
(http://gcc.gnu.org/onlinedocs/) still says "GCC implements the majority
of C++98 (export is a notable exception)...".

http://gcc.gnu.org/gcc-4.3/cxx0x_status.html

Maybe I got confused with "extern template" (which I really don't know
what it means, if it's something different than an export template).
 
J

Juha Nieminen

Gennaro said:
I think I gave up hoping for export in compilers not based on the EDG
front-end when H. Sutter presented his paper "Why We Can't Afford Export"

<http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf>

IMO that paper is a bit misleading in one point: It seems to make it
sound like the only (and imaginary) advantage of export templates is
that you can reorganize your code better (that is, you don't have to put
everything in header files), and that's about it. The section 2.4 is
even titled "provides little or no value".

Unless I have understood export templates incorrectly (and please
correct me if I'm wrong, I really want to get this straight), export
templates allow for better modularity (which is one of the most, if not
the single most important feature of object-oriented programming).

Without export templates (which is the current situation with
basically all compilers) it's impossible to have templated classes and
functions which have private code inside their own compilation unit
(that is, inside a nameless namespace). In other words, non-export
templates can *not* use their own private nameless namespaces because
they don't have their own private compilation unit.

Unless I'm completely mistaken (please correct me if I am), export
templates can use data and code inside a nameless namespace inside the
compilation unit where those templates are implemented. This allows for
greater modularity and data hiding. The larger the amount of data and
code inside this nameless namespace, the more important it would be for
it to be inside that namespace. (For example trying to put hundreds or
even thousands of lines of non-templated code, or unrelated templates,
inside the private section of a template class as static data and static
functions can quickly make the header file a huge mess. With template
functions you can't even do that at all.)
 
G

Gennaro Prota

Juha said:
IMO that paper is a bit misleading in one point: It seems to make it
sound like the only (and imaginary) advantage of export templates is
that you can reorganize your code better (that is, you don't have to put
everything in header files), and that's about it. The section 2.4 is
even titled "provides little or no value".

A comment that I'd actually apply to the paper :) Frankly it is
probably the worst of all H. Sutter's writings, from a technical point
of view.
Unless I have understood export templates incorrectly (and please
correct me if I'm wrong, I really want to get this straight), export
templates allow for better modularity (which is one of the most, if not
the single most important feature of object-oriented programming).

Without export templates (which is the current situation with
basically all compilers) it's impossible to have templated classes and
functions which have private code inside their own compilation unit
(that is, inside a nameless namespace). In other words, non-export
templates can *not* use their own private nameless namespaces because
they don't have their own private compilation unit.
[further elaboration snipped...]

I believe you got it very right. I'm not saying that the world can't
leave without export but certainly the paper presents an unbalanced
view of the matter. Frankly, even the 4.5 person-years... is it such a
show-stopper for a compiler vendor? At EDG, of course, they were just
three at the time, so the issue was a tad different for them :)
 
J

Juha Nieminen

Allen said:
One feature I'd love to see is support for keyword arguments when
calling a function. When a function looks like:

void MyObject::Function(int x, int y, int z = 0 int z2 = 5 int z3 = 10)

it would be nice to be able to do something like:

a.Function(x, y, z3 <-- 20)

to specify a value for z3 without changing/specifying defaults for z and
z2.

Some programmers argue that default function parameter values are
actually bad design, at least if there are many of them. Personally I
can't decide one way or the other (but I do find them handy in many cases).
 

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

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top