The Artima Developer Community
Sponsored Link

Articles Forum
Your C++ Wish List (Editorial)

83 replies on 6 pages. Most recent reply: Jan 1, 2009 9:55 AM by Zar Shardan

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 83 replies on 6 pages [ « | 1 ... 3 4 5 6 ]
lemon head

Posts: 11
Nickname: lemonhead
Registered: Nov, 2006

Re: Your C++ Wish List (Editorial) Posted: Nov 27, 2006 7:39 AM
Reply to this message Reply
Advertisement
Example 3) A little state machine (with performance benefits compared to if-else, if there is a higher number of states)

struct SimpleStateMachine
{
SimpleStateMachine() {current_state=state_A;}
void step() {current_state->step();}
private:
struct State {
virtual void step()=0;
} * current_state;
State state_A { // derived from struct State
virtual void step() {current_state=state_B;}
};
State state_B { // derived from struct State
virtual void step_v() {current_state=state_A;}
}
};

lemon head

Posts: 11
Nickname: lemonhead
Registered: Nov, 2006

Re: Your C++ Wish List (Editorial) Posted: Nov 27, 2006 7:40 AM
Reply to this message Reply
ehm, in better markup
Example 3) A little state machine (with performance benefits compared to if-else, if there is a higher number of states)
 
struct SimpleStateMachine
{
    SimpleStateMachine() {current_state=state_A;}
    void step() {current_state->step();}
  private:
    struct State {
        virtual void step()=0;
    } * current_state;
    State state_A {  // derived from struct State
        virtual void step() {current_state=state_B;}
    };
    State state_B {  // derived from struct State
        virtual void step_v() {current_state=state_A;}
    }
};

Nuwan Abeysinghe

Posts: 1
Nickname: gnu
Registered: Apr, 2007

Re: Your C++ Wish List (Editorial) Posted: Apr 8, 2007 1:54 PM
Reply to this message Reply
C++ has no standard for adding assembly
lines for the source code(Compilers act on there own ways).
why don't we make a standard to this via C++0x ?

Rodolfo Federico Gamarra

Posts: 7
Nickname: rgamarra79
Registered: Sep, 2008

Re: Your C++ Wish List (Editorial) Posted: Oct 10, 2008 11:36 AM
Reply to this message Reply
Hi lemon head. I'm interested in nested classes being able to access "this". In one of your posts you told that the nested object doesn't need to store a reference, that "this can be achieved using the barton-nackmann trick and multi-inheritance, but that's not a nice solution".

Can you give a brief example of the involved technique?

Thanks a lot.

Rodolfo.

lemon head

Posts: 11
Nickname: lemonhead
Registered: Nov, 2006

Re: Your C++ Wish List (Editorial) Posted: Oct 10, 2008 2:46 PM
Reply to this message Reply
[quote]Hi lemon head. I'm interested in nested classes being able to access "this". In one of your posts you told that the nested object doesn't need to store a reference, that "this can be achieved using the barton-nackmann trick and multi-inheritance, but that's not a nice solution".

Can you give a brief example of the involved technique?[/quote]

I am trying to remember :)
I had already given up on the idea, after seeing that noone is interested in it (including Mr. Bj. Str. in persona - but maybe this is because he gets tons of messages a day)
I hope my C++ is not too rusty in the meantime.

You can use this trick, but then it will no longer be a "nested object", but a "parent class".

I'm not even sure anymore if Barton-Nackman is the correct name for the mechanic. Often it is called "curiously recurring template pattern"
http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern

// nested object
 
class Nested {
    virtual void foo_nested() {}
}
 
class Outside {
    void foo_outside() {..}
    Nested nested {
        void foo_nested() {
            // finds the method in class Outside
            foo_outside();
        }
    };  // nested object
}
 
Outside().nested.foo_nested();
 
 
// CRTP solution
 
template<class T>
class NestedT {
    void foo_nested() {
        static_cast<T*>(this)->foo_outside();
    }
}
 
class Outside extends NestedT<Outside> {
    void foo_outside();
}
 
Outside().foo_nested();
 

Rodolfo Federico Gamarra

Posts: 7
Nickname: rgamarra79
Registered: Sep, 2008

Re: Your C++ Wish List (Editorial) Posted: Oct 10, 2008 3:21 PM
Reply to this message Reply
Thanks a lot for your reply lemon head, and nice trick.

I saw also some pages discussing the difference between CRTP and barton-nackmann's trick.

I'll analyze it depth but it seems that it isn't what I was looking for: I'd prefer to avoid the inversion "nested object" to "parent class". Despite, I thought of using it with several nested classes/structs, so I'd say that that rules out this approach.

Maybe storing a pointer to 'this' is the only safe way to do this; which is, put it simply, what Java does.

I'm also considering some way of calculating outer's 'this' from within the nested class. In principle having nested's 'this' and the field offset it could be achieved. Something like

(Within nested)
reinterpret_cast<OuterType*>(this - nested field offset within outer);

But I believe that it could be, so to say, very dangerous. In some webpages a way to calculate the offset is proposed, but it involves dereferencing 0.

At last, see that you used extends in the C++ example (Outside class definition).

Thanks again, cheers.

Rodolfo

lemon head

Posts: 11
Nickname: lemonhead
Registered: Nov, 2006

Re: Your C++ Wish List (Editorial) Posted: Oct 10, 2008 3:35 PM
Reply to this message Reply
You are right, it is absolutely possible via offset calculations. Usually we can assume that the compiler will use the same offset for every object. But still it's stinky...

My proposal was to provide a native syntax for this offset trick, and let the compiler guarantee that it works correctly.

About the Java way: In Java you HAVE to store the reference to 'this', because the nested object is not statically nested in the enclosing object, but dynamically. In C++ we have the nested and enclosing object in the same block of memory.

The static nesting gives a memory benefit, and also reduces indirection. This is usually not worth the trouble, but it can make a lot of sense when programming large data structures with very small atomic objects.

Rodolfo Federico Gamarra

Posts: 7
Nickname: rgamarra79
Registered: Sep, 2008

Re: Your C++ Wish List (Editorial) Posted: Oct 13, 2008 4:07 PM
Reply to this message Reply
Hi lemon head,

Yes, due to Java's heap-allocated objects the pointer is needed. I sketched two template classes, exploring the two approaches.


// Easy, clean. 1 pointer overhead.
template<typename T>
class PointerBasedNestedClass {
protected:
const T* that() const {
return fThat;
}
PointerBasedNestedClass(const T* _that) : fThat(_that) {}
private:
PointerBasedNestedClass();
const T* const fThat;
};

// Risky, dangerous. No overhead.
template<typename T, typename OffsetProvider>
class OffsetBasedNestedClass {
protected:
const T* that() const {
return reinterpret_cast<const T*>(reinterpret_cast<const char*>(this) - OffsetProvider::offset);
}
};


To use the last one, is useful the macro offsetof (defined in <cstddef>). It's interesting to note that, it seems, there're news about that macro in ISO/IEC C++ standard. For instance, take a look at
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2172.html
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2369.pdf

It seems that they're broadening the kind of types the macro may be applied.

The inner cast (to a "sizeof == 1" type) was used to avoid scaling during the arithmetic.

Thanks. Rodolfo.

Zar Shardan

Posts: 1
Nickname: zar
Registered: Jan, 2009

Re: Your C++ Wish List (Editorial) Posted: Jan 1, 2009 9:55 AM
Reply to this message Reply
In my opinion two most important additions to C++ would be:
1) Compile time meta information (Something like Daveed Vandevoorde's metacode).
2) Standard modules - C++ version of Java class files or .net assemblies.

These two features could revolutionize C++ once again.

Compile time meta information.
Although template metaprogramming is a very cool and interesting way of getting some things done, It looks too complicated and has certain limitations that are direct consequence of the lack of the type information during the compilation. Some metadata can be obtained using quite indirect and unnatural tricks, but anyway, that approach is too limited.
Even if it's too difficult to implement all Daveed's ideas, at least some way to iterate over class/template's members/member functions and their types would be very useful.
Something resembling .net attributes but available during the compile time instead of (or in addition to - optionally) runtime - would be awesome. This would enable a whole gamut of new powerful techniques.
All this additions revolving around the metadata issue would greatly reduce the need for code generation tools for C++ resulting in more portable elegant and generic solutions.

Optionally, making this rich metadata (extended RTTI) available during the runtime would be also handy, but I'm not a big fan of that idea because it might encourage structurally simple but inefficient Java/C# style solutions.

2) Standard modules.
This would make possible to share C++ binaries across different OSes and platforms as long as the CPU instruction set is the same. Platform specific code could be isolated in platform specific binaries with the same C++ interfaces.
Ability to include those modules would also be nice. This is already implemented in MSVC:
#import "some.dll"
Just make it something portable and standard.

3) I agree that access to host class members/functions from the nested class could be useful in some cases and not too difficult to implement. I believe implementation complexity would be similar in a way to multiple (virtual) inheritance.
From the conceptual point of view it's no uglier than MI itself or friends for example.

multiple levels could be handled with either scope resolution operator, or additional keyword (host?):

1) OuterHostClassName::this->someFunc();
or
2) host.host.someFunc();

whichever feels more consistent with C++ syntax.

Flat View: This topic has 83 replies on 6 pages [ « | 3  4  5  6 ]
Topic: Three Minutes to a Web Service Previous Topic   Next Topic Topic: Safe Labels in C++


Sponsored Links



Google
  Web Artima.com   

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