www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - C++ member function translations

reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Can someone who's figured this out tell me what the translations for the 
following C++ member function signatures would be in D 2.0?

C++:
const Foo& func(const Bar&) const;
const Foo& func(Bar&) const;
const Foo& func(const Bar&);
const Foo& func(Bar&);
       Foo& func(Bar&) const;
       Foo& func(Bar&);

And for D I'm interested in both the struct and the class case for Foo.
Let Bar be a D struct in all cases.
I'm after similar semantics so Foo& as a D class is going to be just 
Foo, and as a D struct I presume it should be 'ref Foo'.

C++:      const Foo& func(const Bar&) const;
D class:
D struct:

C++:      const Foo& func(Bar&) const;
D class:
D struct:

C++:      const Foo& func(const Bar&);
D class:
D struct:

C++:      const Foo& func(Bar&);
D class:
D struct:

C++:      Foo& func(Bar&) const;
D class:
D struct:

C++:      Foo& func(Bar&);
D class:
D struct:
Jul 26 2007
next sibling parent Christian Kamm <kamm.incasoftware shift-at-left-and-remove-this.de> writes:
 Can someone who's figured this out tell me what the translations for the
 following C++ member function signatures would be in D 2.0?

I don't think literal translations are possible, especially since the notions of constness in D and C++ are so different. Here's a try ignoring the basic differences (transitivity...) anyway. I'll split the questions differently though, easy ones first. ? How to return const Foo& and Foo& if Foo is a class? const(Foo) and Foo should do it. ? How to pass Bar& if Bar is a struct? ref Bar ? How to return const Foo& and Foo& if Foo is a struct? Can't return ref parameters, so Foo* and const(Foo*) seem to be the only option. ? How to pass const Bar& if Bar is a struct? ref const(Bar) currently causes a compiler segfault (bug 1319), but I'm not sure if it'd have the right behaviour anyway. So it's const(Bar*) again... That's all not really satisfacty. If there are better options, I'd like to know them too. Regards, Christian
Jul 27 2007
prev sibling parent reply Daniel919 <Daniel919 web.de> writes:
Classes are always passed by reference, so there is no need for &.
Structs are value types, they don't have a reference, so a ptr has to be 
used.

It's not possible to overload member functions by attribute.
So this is not possible:
class Foo {
     const void func() {/*don't change any fields*/}
     void func() {/*changes might happen*/}
}
Just like it's neither possible to overload by public / private.


 C++:      const Foo& func(const Bar&) const;

const const(StFoo)* cfunc(const(StBar)*)
 C++:      const Foo& func(Bar&) const;

const const(StFoo)* cfunc(StBar*)
 C++:      const Foo& func(const Bar&);

const(StFoo)* func(const(StBar)*)
 C++:      const Foo& func(Bar&);

const(StFoo)* func(StBar*)
 C++:      Foo& func(Bar&) const;

const StFoo* cfunc(StBar*)
 C++:      Foo& func(Bar&);

StFoo* func(StBar*) Best regards, Daniel
Jul 27 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Daniel919 wrote:
 Classes are always passed by reference, so there is no need for &.
 Structs are value types, they don't have a reference, so a ptr has to be 
 used.

Can't you at least use a 'ref StBar' as a parameter? And in response to Christian -- I would have expected 'const ref StBar' to be the way to translate 'const StBar&' from C++. That doesn't work? Note that in C++ you can't re-bind a reference, so they're effectively like D final. Thus in terms of acting like C++ it makes sense for const to apply to both the ref and the contents. ..... hmm but I guess 'ref' isn't a type constructor in D it's just a parameter passing mechanism. Bummer. Anyway, that's a big disappointment because passing large structs around by const references was one of the main reasons I wanted D to get const. But it's not possible.
 It's not possible to overload member functions by attribute.
 So this is not possible:
 class Foo {
     const void func() {/*don't change any fields*/}
     void func() {/*changes might happen*/}
 }
 Just like it's neither possible to overload by public / private.

I thought 'const' served as a type constructor not an attribute. But you're saying D's 'const' applied to a method isn't just changing the type of the hidden 'this' parameter, it's an attribute of the whole method instead? Odd. Does that approach have some great virtue to it?
  > C++:      const Foo& func(const Bar&) const;
 const const(ClFoo) cfunc(const(StBar)*)
 const const(StFoo)* cfunc(const(StBar)*)
 
  > C++:      const Foo& func(Bar&) const;
 const const(ClFoo) cfunc(StBar*)
 const const(StFoo)* cfunc(StBar*)
 
  > C++:      const Foo& func(const Bar&);
 const(ClFoo) func(const(StBar)*)
 const(StFoo)* func(const(StBar)*)
 
  > C++:      const Foo& func(Bar&);
 const(ClFoo) func(StBar*)
 const(StFoo)* func(StBar*)
 
  > C++:      Foo& func(Bar&) const;
 const ClFoo cfunc(StBar*)
 const StFoo* cfunc(StBar*)
 
  > C++:      Foo& func(Bar&);
 ClFoo func(StBar*)
 StFoo* func(StBar*)

A lot of parentheses and stars. :-( --bb --bb
Jul 27 2007
parent Christian Kamm <kamm.incasoftware shift-at-left-and-remove-this.de> writes:
 And in response to Christian -- I would have expected 'const ref StBar'
 to be the way to translate 'const StBar&' from C++.  That doesn't work?

Well, I'm pretty sure that 'const ref StBar' is the same as 'ref const(StBar)' for function arguments. And the reason why I think 'ref const(StBar)' is not going to be a 'const StBar&' equivalent is: --- struct StBar { int i; } void foo(ref const(StBar) b) { b.i = 2; // this should be allowed... } void main() { StBar bar; bar.i = 1; foo(b); const(StBar) cbarcopy = bar; cbarcopy.i = 2; // ... because this is allowed } --- I.e. making a plain-data struct containing no references const doesn't change its behaviour at all. Christian
Jul 28 2007