The Artima Developer Community
Sponsored Link

Articles Forum
A Brief Look at C++0x

150 replies on 11 pages. Most recent reply: Nov 23, 2006 11:19 AM by lemon head

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 150 replies on 11 pages [ « | 1 ... 7 8 9 10 11 | » ]
Joel Redman

Posts: 3
Nickname: redmjoel
Registered: Dec, 2005

Re: A Brief Look at C++0x Posted: Jan 16, 2006 12:08 PM
Reply to this message Reply
Advertisement
Here's my top 3 wish list item:

1. Lambdas -- at least at the level of Boost::Lambda
what: A way to pass functions into the STL
why: Without a lambda-ish way of passing a function object into the STL algorithms and containers, there will not be a widespread use of the STL algorithms. Currently, it is a big headache to use the (for instance) std::find algorithms. Much more so than writing your own loops.

2. Garbage collection
what: Automatic resource tracking (as in C++/CLI)
why: Takes the burden of tracking memory away from the programmer if not needed. This is something that C++/CLI has gotten right, and it would be shame to not be able to use it in a wider context. The C++/CLI version doesn't pass an undue burden onto the run-time, as it would only be necessary to run the garbage collecter in code which actually uses the garbage collection keywords. This is something which is easily visible at link-time. It is possible that this could be an "optional" part of the standard, so that places where it is inappropriate would not have to implement it. This would be the case for DSPs for instance.

3. Initialization of collections
what: Support for "vector<int> list = {1, 2, 3, 4, 5};" syntax
why: This is a big headache for both novice users and experienced programmers. The current standard also violates the design goal of making user types equivalent to built-in types.

Aleksey Gurtovoy

Posts: 1
Nickname: agurtovoy
Registered: Jan, 2006

Re: A Brief Look at C++0x Posted: Jan 19, 2006 8:29 PM
Reply to this message Reply
> I wouldn't critize Boost for being "modern". I think the
> real problem is that many "boosters" are interested in
> "neat/advanced" libraries rather than in providing
> yet-another, but more standard and usable directly useful
> component.

That's quite an accusation. Do you have any data to support it?

> For example, why weren't boost threads, boost
> sockets, boost XML, boost unicode, and boost files among
> tthe very first boost components?

Because, beleive it or not, building any sizeable domain-specific library that a skilled C++ engineer would be satisfied with actually requires lots and lots of these low-level "neat" libraries [1] that the C++ standard is missing.

[1] Often in the form of both the actual code and the conceptual foundation.

> Such foundation for
> applications are hard and non-glamorous - it takes a major
> effort to get people to create and maintain such
> components.

Right, and, say, Boost.Type Traits, Boost.Graph and Boost.Regex (one of the very first Boost libraries) were a piece of cake, totally glamorous, and took no effort to create and mantain.

Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: A Brief Look at C++0x Posted: Jan 23, 2006 8:28 AM
Reply to this message Reply
Here are some other interesting ideas. I am posting them not as 'things I want', but as interesting ideas for discussion:

1) friend access attribute customized on classes/functions that can have access. Example:


class MyClass {
public:

protected:

private:
int a;

friend(MyOtherClass1, MyOtherClass2, MyFunction1):
int b;
};


2) truly private implementations. The header files will contain 'interface' classes which might or might not have all the members, and the implementation file will declare the actual internal implementation of the class as well as private fields/methods not visible in the header file. Example:


//header file
interface MyTruePrivateClass {
public:
void publicMethod();

private:
};

//implementation file
implementation MyTruePrivateClass {
public:
void publicMethod() {
}

private:
int truePrivateData;
void truePrivateMethod();
};


The compiler should keep a hidden table of object sizes to use with operator new or member declaration, as well as for checking if implementation of object already exists.

3) custom pointer syntax. Example:


template <class T> class SmartPtr@ : _SmartPtrBase {
public:
...
};

template <class T> class WeakPtr^ : _WeakPtrBase {
public:
...
};

//using weak and smart pointers
Foo @foo1 = new Foo;
Bar ^bar1 = new Bar;
(@foo1).data = 5;
(^bar1).data = 5;


4) more functionality in operator new, using a special class new<T>. For those classes that have a specialization of new, it is the New<T> that is called instead of operator new. This will allow various actions on an object not possible now. Example:


class Foo {
};

template <> new<Foo> {
public:
//called instead of operator 'new'
static Foo *operator new(size_t size) {...}

//called instead of operator 'delete'
static void operator delete(Foo *foo) {...}

//called implicitely after object constructor
static void created(Foo *foo) {...}

//called implicitely after object destructor
static void deleted(Foo *foo) {...}
};


The above will allow things like this:

a) performing actions that depend on allocated type; for example registering a finalizer in a garbage collector.
b) performing actions that depend on after constructors have been called; for example, registering an object somewhere, while calling a virtual method of the object (not possible before instantiation).

5) accessing struct/class members with array syntax; operator lengthof that returns number of elements of array/tuple. This is necessary for compile-time introspection. Example:


struct MyStruct {
int field1;
double field2;
float field3;
};

template <> void doSomething(MyStruct *s, int field);
template <> void doSomething(MyStruct *s, double field);
template <> void doSomething(MyStruct *s, float field);

void processMyStruct(MyStruct *s) {
//intrinsic function 'lengthof' returns length of tuple
for(int i = 0; i < lengthof(*s); ++i) {
//using fields of a struct with array syntax; different version of 'doSomething' is invoked for each field
doSomething(s, (*s)[i]);
}
}


6) aspects/introspection by classes for classes. Example:


//my class
class Foo {
public:
void doSomething();
};

//class of class Foo
class<Foo> {
public:
//aspect overloading
void doSomething() {
log << "doSomething was called\n";
Foo::doSomething();
}
};

Foo *foo = new Foo;
foo->doSomething(); //the aspect is invoked, instead of the method.


Very useful for debugging purposes and other operations. With this capability, point #4 above is reduntant, as operator new can be a member of the aspect classes.

7) instance creation by namespace string. Example:


Object *myObject = new "MyApp::MyClasses::Foo"(1, 2, 3);


Useful for loading modules at run-time. The compiler should place an internal array of class information in each executable/library.

8) classes that can be defined/extended on the point of declaration. For example:


class Foo {
public:
virtual void action();
};

Foo *foo1 = new Foo() {
void action() {
printf("subclassed!\n");
}
};

Foo foo2() {
void action() {
printf("subclassed!\n");
}
};

sort(mydata, class MyFunctor() { bool operator ()(int a, int b) { return false }});


Useful for for callbacks, etc.

9) local functions. Example:


void outterFunction() {
int i;

void innerFunction() {
int j = i + 1;
}

innerFunction();
}


It's quite easy to achieve. The inner function's stack should come right after the outter function's stack; think about is as struct inheritance. Stack frames should be dealt with as locally defined structs, and local variables should be accessed as member objects of the function. For example:


outterFunction.i = 5;


Local functions allow for interesting algorithms.

10) formalize CPU context. The standard library should provide a CPU context class as well as methods to get/set CPU context. Since C++ is a high-level language for a low-level environment, C++ should provide such functionality. This functionality will allow for user threads, user multithreaded garbage collection, co-routines, tail call optimization etc. The API should be fairly abstract: the CPU context should be handled as an array of bytes, but also as a struct with named registers. The API should offer the following functionalities:

a) setting and getting the CPU context.
b) getting the stack information (top and bottom address).
c) using the stack: push, pop.
d) setting up the next address to execute.

11) arbitrary length integer, real arithmetic; fractions; ranges. I think the standard library should have those.

12) sets. Like enumerations, but member values can be objects. Example:


setdef MyColor : Color {
Red = Color(255, 0, 0),
Green = Color(0, 255, 0),
Blue = Color(0, 0, 255)
};

setdef Day : const char * {
Sun = "Sunday",
Mon = "Monday",
Tue = "Tuesday"
};


Sets could be used like arrays or enumerations. Example:


MyColor c1 = Blue;
Color c2 = MyColor[2];


The reason sets are useful is the same as enumerations: they limit the chances of using the wrong value (as well as provide names for standard values).

Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: A Brief Look at C++0x Posted: Jan 23, 2006 8:40 AM
Reply to this message Reply
Some new stuff that I just came up with:

1) constructor forwarding. Just as destructors are forwarded, so should constructors. If a derived class has no constructor, then it gets the constructors of the base class. This will make it easier to use the 'inherit from template parameter' pattern. Example:


template <class T> class MyClass : public T {
public:
};

class MyBase1 {
public:
MyBase1(const char *str);
};


class MyBase2 {
public:
MyBase2(double);
};

new MyClass<MyBase1>("aaa");
new MyClass<MyBase2>(3.14);


2) template classes as friends, not only template specializations. Often the need arises for a template class to be friend of a non-template class, but it is not possible with the language as it is now without an intermediate class. Example:


class MyClass {
public:

private:
//make all specializations of MyTemplate friend to this
friend class MyTemplate;
};

template <class T> class MyTemplate {
public:
};

Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: A Brief Look at C++0x Posted: Jan 23, 2006 8:46 AM
Reply to this message Reply
(sorry guys for replying to myself; is there an 'edit' button? have I missed it?)

Yet another one:

1) if a class does not have a parameterized constructor, and the programmer uses a constructing call with operator =, then the compiler should call the default constructor, then the operator =. Example:


class MyClass {
public:
MyClass();
MyClass &operator = (int x);
};

MyClass c = 1;

Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: A Brief Look at C++0x Posted: Jan 23, 2006 9:37 AM
Reply to this message Reply
Nested comments. Some time it is needed to just comment out a piece of code that includes block comments. Example:


/+ nested comments
/* block comments */
//line comments
+/

Dmitriy Litskalov

Posts: 5
Nickname: limit
Registered: Jan, 2006

Re: A Brief Look at C++0x Posted: Jan 24, 2006 3:14 AM
Reply to this message Reply
> 12) sets. Like enumerations, but member values can be
> objects. Example:
>
>

> setdef MyColor : Color {
> Red = Color(255, 0, 0),
> Green = Color(0, 255, 0),
> Blue = Color(0, 0, 255)
> };
>
> setdef Day : const char * {
> Sun = "Sunday",
> Mon = "Monday",
> Tue = "Tuesday"
> };
>


I think that better to extend enum keyword functionality and trait it as predefined template with one template parameter that denote base type for enumeration constants.
In this case your examples can be rewritten:


enum MyColor<Color>
{
Red = Color(255, 0, 0),
Green = Color(0, 255, 0),
Blue = Color(0, 0, 255)
};

enum Day<const char *>
{
Sun = "Sunday",
Mon = "Monday",
Tue = "Tuesday"
};


It is also solve a problem with exact base type for ordinary enumerations. C++ rules in this aspect is not so easy to remember.


enum A<int>
{
ONE = 1;
};
enum B<unsigned>
{
TWO = 2;
};


Of course enum C {} is also possible. In this case old rules for base type would apply.

Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: A Brief Look at C++0x Posted: Jan 24, 2006 6:02 AM
Reply to this message Reply
Thanks for the reply. Good idea about the enum syntax. Any other comments? anyone?

Dave Abrahams

Posts: 8
Nickname: abrahams
Registered: Oct, 2004

Re: A Brief Look at C++0x Posted: Feb 21, 2006 12:21 PM
Reply to this message Reply
> One technical problem (that the boosters are trying to
> find a solution to) is that boost is a monolith. This has
> been a problem with outher libraries also, such as ACE.
> For example, say I want to be able to download and use
> just the regular expressions and don't want any other
> library to complicate my system, how can I get just
> boost::regex and what it depends on and nothing else.

First of all, let me acknowledge that Boost has (intentional) internal dependencies. That said, while I'm sure Bjarne didn't mean it that way, most of the above is misleading at best. So let me clear a few things up:

1. Boost is not a monolith in any sense, except maybe that we don't provide separate downloads of individual libraries.

2. As of a year or two ago, Boost's coupling was *nothing like* ACE's. A friend of mine was working for a company that built refactoring software that could graph dependencies. When they threw the technology at ACE, it quickly became known as "the blob": because everything was linked to everything else, you couldn't make out the individual edges in the graph. All you could see was a big black mass. When we did the same with Boost, there were a few small areas that could be improved, but for the most part the dependencies were hierarchical and non-cyclic. I don't know what has happened with ACE recently (things may have improved), but Boost has maintained the practices that resulted in that low coupling.

3. We have a tool that can separate out individual libraries and their dependencies: http://www.boost.org/tools/bcp/bcp.html. So far it has been a little overly conservative, but we are working on ways to make it less so. For example, some dependencies only arise when optional features of a given library are used. We're adding features to make sure that those dependencies are pruned when users don't explicitly request the optional features.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

Piet Zaber

Posts: 1
Nickname: cyberpoep
Registered: Feb, 2006

Re: A Brief Look at C++0x Posted: Feb 23, 2006 7:55 PM
Reply to this message Reply
Sorry for interrupting this discussion but I'm new to C++ and when I saw Bjarne writing an article I thought wow maybe this C++ Genius may know the real C++ Genius http://www.cplusplusgenius.wagoo2.com/

Is there anyone in this forum who knows this guy. Is he really a genius? I wish he would upload the software he's refering to on his downloads page.

Ok you can continue discussing this new C++ thing, but please let me know if you know anything about this guy.

Thanks

Dave Abrahams

Posts: 8
Nickname: abrahams
Registered: Oct, 2004

Pass By Name Posted: Mar 4, 2006 11:32 PM
Reply to this message Reply
> optional C++ extensions to macro system
> what: Add extensions to the preprocessing macro system
> such that old C macros work, but that programmers can take
> advantage of macros defined at a "conceptual level"
> instead of at a textual level -- perhaps by adjusting the
> parse tree instead of the source code.
> why: While C++ features like templates and const data can
> elliminate the need for many C macros, some programmers
> like the possibility of adding keywords to their own
> programs, without being constrained by template syntax,
> etc. This generalized construct sould then be used to
> define "pass by name" or similar wishes.

FYI, there's a library solution for "pass by name:" http://www.boost.org/libs/parameter

Hillel Sims

Posts: 1
Nickname: thesim
Registered: Mar, 2006

C++ Posted: Mar 21, 2006 10:19 PM
Reply to this message Reply
Hello hello. Is this thing still on?

- Re, lambdas: Does anyone use bind()?

- Re, threads: A reliable model of threading in C++ will not exist until exceptions and cancellation are unified. I almost fear it is too late for this in the general population though, due to the entrenched legacy behavior on most C++ platforms.

Jennifer Mölsä

Posts: 3
Nickname: semantic
Registered: May, 2006

Re: A Brief Look at C++0x Posted: May 21, 2006 12:46 PM
Reply to this message Reply
I realise I am joining in *very* late in the discussion,
but here goes:

1. default constructor

what:
The default ctor should be automatically defined
(if the user does not provide one) *even if* the user
provides other ctors.

why:
C++ supports value oriented programming (where classes
can be used in the same way as builtin types), but
having the default constructor behave differently
(in this regard) than the copy constructor is confusing
(as to why) and unneccessary.
If you do not want a value class, inhibit
the dflt ctor the same way you would inhibit the copy ctor.

2. hiding vs overloading

What:
A function "f" (with unique argument types) in a class
"Derived" should not hide other f in the base class "Base".
It should overload the other f in the base class.

Why:
Every time I have declared a "f" in a subclass
(with other f in "Base", it has been with the intention
to overload. Never to hide. Hiding violates LSP.


This behaviour in C++ has always surprised me,
and I have never felt that it has been right
(in 15 years of C++ programming).
I know about "using Base::f" but it seems better to have
that behaviour as default (that is, overloading).


3. overloading resolution

What:
When looking for candidate (member) functions,
do not consider functions that I can not access
(eg. private functions). Only consider functions that are
accessible to me at that point.

Why:
The whole idea of "separating interface from implementation"
is about not needing to the implementation. It is not very
robust if suddenly I can not compile a piece of code because
the implementation needed and declared (in the class)
a new function that happens to be the best match
*if I could have used it*.

I know about the pimpl idiom, but this should have the
(in my vew) correct behaviour for the "basic" class usage
already.

John Wellbelove

Posts: 1
Nickname: bismuth
Registered: Aug, 2006

Re: A Brief Look at C++0x Posted: Aug 17, 2006 11:34 AM
Reply to this message Reply
Not sure if this has been mentioned before, but how about adding the ^^ as a logical exclusive OR boolean operator?

It would complete the set, along with the current || and &&

Having &&= ||= and ^^= would be nice too.

Yes, I know you can do all of this with the binary operators, but wouldn't it be better to do it properly?

lemon head

Posts: 11
Nickname: lemonhead
Registered: Nov, 2006

My Wishes Posted: Nov 23, 2006 11:15 AM
Reply to this message Reply
1. Variadic templates
(as suggested and discussed elsewhere)



2. Anonymous nested objects (here: c.nested) with access to the containing object (here: c of type C). It should be possible to derive their type from a base class (here: 'Base').

struct Base {
    virtual void foo() {}
};
 
struct C {
    void foo_C() {}
 
    // not possible in c++ nowadays
    Base {
        void foo() {foo_C();}  // nowadays, c.nested has no access to the members of c.
    } nested; 
 
    // not possible in c++ nowadays
    Base nested {...}; 
 
    // not possible in c++ nowadays
    struct {...} nested : Base; 
 
    // not possible in c++ nowadays
    struct : Base {...} nested; 
 
    // not possible in c++ nowadays
    struct {...} nested; 
} c;
 
Base* b = c.nested;
b->foo();

To access the members of c, c.nested doesn't need to store a reference. The adress difference of c and c.nested is the same for any object c with type C, so accessing c.foo_C() would technically be no problem.

(Nowadays, this can be achieved using the barton-nackmann trick and multi-inheritance, but that's not a nice solution)



3. The same for nested functions - they should as well be able to access other members of the containing class or function.



4. A "This" keyword to identify the type of "*this".

template<... ... ...> class A {
    typedef A<... ... ...> This;  // too clumsy, should be done by the compiler!!
};




5. exit loops with a break statement with return value

for(...) {
   ...
   if(..) break end_of_file(i);
   else if(..) break end_of_file(i+5);
   else if(..) break found_error("parsing_error");
   ...
   if(..) break found_error("mature content");
}
 
cout << "normal_break" << endl;
 
label end_of_file(int line_number) {
   cout << "end of file reached in line "<< line_number << endl;
}
 
cout << "normal break or end of file finished" << endl;
 
label found_error(char* message) {
   cout << "found error " << message << endl;
}
 
cout << "normal break or eof or found an error" << endl;

These labels are similar to nested functions. The difference is, when they are finished, execution will continue in the line where the label block ends.

The same could be achieved with helper functions, but then the code would be scattered in places where it is hard to find.

Flat View: This topic has 150 replies on 11 pages [ « | 7  8  9  10  11 | » ]
Topic: JSF and JSP: What's New in Java EE 5 Previous Topic   Next Topic Topic: My Most Important C++ Aha! Moments...Ever


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us