Thread overview
C++ member function translations
Jul 27, 2007
Bill Baxter
Jul 27, 2007
Christian Kamm
Jul 27, 2007
Daniel919
Jul 27, 2007
Bill Baxter
Jul 28, 2007
Christian Kamm
July 27, 2007
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:
July 27, 2007
> 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

July 27, 2007
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(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*)


Best regards,
Daniel
July 27, 2007
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
July 28, 2007
> 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