February 09, 2009
Weed Wrote:

> >>> Well, D class code here is not equivalent to C++ class code. D code has more features, namely, it's polymorphic: C.opAdd is able to work with classes, derived from C, while corresponding C++ code is unable to do so.
>  But I do not understand in what here problem. In C++ is impossible to
> do overloading with "virtual" keyword?
> Probably I badly know C ++, sorry.

In C++ you can't pass object derived from C to opAdd method. In D you can.
February 09, 2009
On 2009-02-09 07:00:56 -0500, Weed <resume755@mail.ru> said:

>> No. By forbiding the cases that leads to slicing, like returning a
>> polymorphic object by value.
> 
> Let's think, can there are other ways to solve problem?
> 
> Here, for example my reasons:
> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=81958

I'm 
> 
not sure I'm getting what you mean in that post.

It seems like you want the ability to copy classes, and thus pass them by value, but only when there would be no type conversion.

I'm not getting where this can be useful though: by forcing your classes to be of a specific type, with no derived types allowed, you're losing polymorphism. The only advantage you have is that your type can be derived from another so you can reuse some of its implementation. There are other ways to acheive that in D however (mixins come to mind).

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

February 09, 2009
Rainer Deyke wrote:
> Andrei Alexandrescu wrote:
>> The slicing problem exists in spades in this example, or better put its
>> converse (your code will fire asserts when it shouldn't). The reason is
>> rather subtle, so please try the code out to edify yourself.
> 
> You're referring to the automatically generated copy constructor in
> class 'avatar' which calls the copy constructor in class 'person',
> right?  That's a bug in my silly untested example code, but it's not the
> slicing problem.

It's also a problem whenever you use avatar by value. It's only by programmer discipline that you avoid the slicing problem.
February 09, 2009
On 2009-02-09 07:34:44 -0500, Michel Fortin <michel.fortin@michelf.com> said:

> The only advantage you have is that your type can be derived from another so you can reuse some of its implementation. There are other ways to acheive that in D however (mixins come to mind).

That said, I'm not against adding struct inheritance if it can be done in a way that avoids slicing problems. I think this can be acheived by making slicing innoculous:

1. forbid overriding base members
2. forbid destructors in derived strucs (or else slicing would lose the destructor)

Open questions:
Is that constraining enough to avoid slicing problems?
Do these constrains make the feature irrelevant?

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

February 09, 2009
Michel Fortin wrote:
> On 2009-02-09 07:00:56 -0500, Weed <resume755@mail.ru> said:
> 
>>> No. By forbiding the cases that leads to slicing, like returning a
>>> polymorphic object by value.
>>
>> Let's think, can there are other ways to solve problem?
>>
>> Here, for example my reasons:
>> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=81958 
>>
> 
> I'm
>>
> not sure I'm getting what you mean in that post.
> 
> It seems like you want the ability to copy classes, and thus pass them by value, but only when there would be no type conversion.
> 
> I'm not getting where this can be useful though: by forcing your classes to be of a specific type, with no derived types allowed, you're losing polymorphism. The only advantage you have is that your type can be derived from another so you can reuse some of its implementation. There are other ways to acheive that in D however (mixins come to mind).
> 

The one case I could think of was the strategy pattern: no data is added (including, no virtual functions) -- the only thing that's added is a different implementation of an existing virtual function. In such a situation, the slicing problem cannot happen. You can have an array of polymorphic types. But the language won't allow it.

However, I've encountered this problem in C++ as well. Allowing stack-based classes is NOT sufficient to solve it. What you actually want is a struct with a vtable pointer stored IN the struct itself (rather than one instance of the vtable per struct).
February 09, 2009
Weed wrote:
> And if I need some different such combinations? For each it is necessary
> to write such 8-10 lines? This is terrible!

You need to add those lines for every method you need virtual dispatch with for your value type. It's an overhead of three lines per method, two for the interface (declaration and member), and one extra line where you create the struct. If you're reasonable, your struct constructor will create a default instance.

So, it's not that great an overhead.
February 09, 2009
Kagamin:

>Well, D class code here is not equivalent to C++ class code. D code has more features, namely, it's polymorphic: C.opAdd is able to work with classes, derived from C, while corresponding C++ code is unable to do so. If you can't use polymorphism, why do you use classes?<

I'd like to create a more apples-to-apples comparison, so if you have suggestions regarding how to improve the code I am willing to fix things and redo the timings. Maybe adding a 'virtual' to the C++ method?

I too have done some benchmarks, see timings, notes and code here: http://leonardo-m.livejournal.com/76547.html

Bye,
bearophile
February 09, 2009
Kagamin пишет:
> Weed Wrote:
> 
>>>>> Well, D class code here is not equivalent to C++ class code. D code has more features, namely, it's polymorphic: C.opAdd is able to work with classes, derived from C, while corresponding C++ code is unable to do so.
>>  But I do not understand in what here problem. In C++ is impossible to
>> do overloading with "virtual" keyword?
>> Probably I badly know C ++, sorry.
> 
> In C++ you can't pass object derived from C to opAdd method. In D you can.

I am do not agree with you:

// C++:
class C {
    public:
        virtual void doSomething( C src ) {}
};

class C2 : public C {
};

int main( int argc, char* argv[] ) {
    C c;
    C2 c2;

    c.doSomething( c2 );

    return 0;
}
February 09, 2009
Michel Fortin пишет:
> On 2009-02-09 07:00:56 -0500, Weed <resume755@mail.ru> said:
> 
>>> No. By forbiding the cases that leads to slicing, like returning a polymorphic object by value.
>>
>> Let's think, can there are other ways to solve problem?
>>
>> Here, for example my reasons: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=81958
>>
> 
> I'm
>>
> not sure I'm getting what you mean in that post.
> 
> It seems like you want the ability to copy classes, and thus pass them by value, but only when there would be no type conversion.
> 

Yes, this is the easiest way that came to my head


> I'm not getting where this can be useful though: by forcing your classes to be of a specific type, with no derived types allowed, you're losing polymorphism.

Yes

> The only advantage you have is that your type can be
> derived from another so you can reuse some of its implementation.

And still able to pass class instance through a stack!

And I do not propose to remove the traditional class in the heap

> There
> are other ways to acheive that in D however (mixins come to mind).
> 
February 09, 2009
Christopher Wright пишет:
> Weed wrote:
>> And if I need some different such combinations? For each it is necessary to write such 8-10 lines? This is terrible!
> 
> You need to add those lines for every method you need virtual dispatch with for your value type. It's an overhead of three lines per method, two for the interface (declaration and member), and one extra line where you create the struct. If you're reasonable, your struct constructor will create a default instance.
> 
> So, it's not that great an overhead.

Do not be surprised that so many continue to write in C++! :)