digitalmars.D.learn - const and non-const member function
- Frank Fischer (35/35) Jul 25 2007 Hi,
- Christian Kamm (12/19) Jul 25 2007 I don't think it's possible (yet). Trying
- Chris Nicholson-Sauls (15/40) Jul 25 2007 I may be wrong, but I think the idea is that a method either is or isn't...
- James Dennett (16/54) Jul 25 2007 The normal reason (coming from C++) for having overloads by
- Christian Kamm (31/41) Jul 26 2007 Well, the original poster basically wanted it to be possible to have
- Frits van Bommel (8/23) Jul 26 2007 How about this for method-const:
- Christian Kamm (14/24) Jul 26 2007 I thought the same thing: putting the const/invariant after the return t...
- Kirk McDonald (10/36) Jul 26 2007 I have a radical notion. We could place it after the parameter list!
- Regan Heath (38/48) Jul 26 2007 Initially I thought it would overload on the 'ref' part of the delegate
Hi, I'm just playing around with const in DMD 2.003 and I have a question. In C++ it is possible to have a const and a non-const member function with the same name and parameter types. It depends on the type of the reference to the object which function is called: class A { public: int myfunc() { return 0; } int myfunc() const { return 1; } }; A a; a.myfunc(); // returns 0 const A& b = a; b.myfunc(); // returns 1 Is something like this possible in D? Another example would be with different return-types: class B { A a; public: A& myfunc() { return a; } const A& myfunc() { return a; } }; (of course, in D you don't need explicit references but the idea is the same). Furthermore, is it possible to overload opApply(...) so it can be called on non-const objects and const objects, and the non-const variant has read-write access: foreach(ref x; obj) x = 1; // possible for non-const 'obj' foreach(ref x; cast(const(Obj))obj) x = 1; // ERROR for const 'obj' foreach(x; obj) writefln("%d", x); // Ok for both, const and non-const 'obj' What would be the D-way of doing this? I need this access to provide the correct member functions in some of my D-libraries I write, since I want to have const-versions of my objects. Thanks, Frank
Jul 25 2007
In C++ it is possible to have a const and a non-const member function with the same name and parameter types. ... Is something like this possible in D?I don't think it's possible (yet). Trying class Foo { void bar() {} const void bar() {} } gives me an error. I'm not sure if it is by design or just not working yet.Furthermore, is it possible to overload opApply(...) so it can be called on non-const objects and const objects, and the non-const variant has read-write access:Having that would pretty much depend on being able to have a opApply and a const opApply. I tried by using two functions with different names, but the compiler segfaulted on a ref const(Struct*). Cheers, Christian
Jul 25 2007
Christian Kamm wrote:I may be wrong, but I think the idea is that a method either is or isn't const-safe, and the difference between const and mutable references to the object is supposed to be in the availability of methods, not in their behavior. While I'm sure there's some percentage of the time subtle behavioral changes could be desirable, I don't believe const-method overloading is meant to happen. That said, a few demonstrative cases sometimes do wonders. :) (I'm also not 100% pleased with the 'const R M(){}' syntax for declaring const methods... To me it reads as a function M() returning 'const R'. Yes I know the syntax for that is 'const(R) M(){}' and no I don't have a better idea right off hand. I don't care for the C++ 'R M() const {}' either. Wasn't there something like 'R M:const(){}' volleyed back when the const discussions first happened?) -- Chris Nicholson-SaulsIn C++ it is possible to have a const and a non-const member function with the same name and parameter types. ... Is something like this possible in D?I don't think it's possible (yet). Trying class Foo { void bar() {} const void bar() {} } gives me an error. I'm not sure if it is by design or just not working yet.Furthermore, is it possible to overload opApply(...) so it can be called on non-const objects and const objects, and the non-const variant has read-write access:Having that would pretty much depend on being able to have a opApply and a const opApply. I tried by using two functions with different names, but the compiler segfaulted on a ref const(Struct*). Cheers, Christian
Jul 25 2007
Chris Nicholson-Sauls wrote:Christian Kamm wrote:The normal reason (coming from C++) for having overloads by constness is when the return value should differ in constness. The C++ community would frown on code with differences between const and non-const member functions other than those that directly relate to constness. A trivial almost example is any object returning a reference to a component of itself; if the object is const, then the reference to its component should not allow modification, but if the object is non-const, then modification of its component may well be reasonable. (There's a separate debate that I don't want to get into about whether it's poor design to expose references to components. If that's a sticking point to you, imagine that the relationship is "uses" rather than "is composed of".) -- JamesI may be wrong, but I think the idea is that a method either is or isn't const-safe, and the difference between const and mutable references to the object is supposed to be in the availability of methods, not in their behavior. While I'm sure there's some percentage of the time subtle behavioral changes could be desirable, I don't believe const-method overloading is meant to happen. That said, a few demonstrative cases sometimes do wonders. :)In C++ it is possible to have a const and a non-const member function with the same name and parameter types. ... Is something like this possible in D?I don't think it's possible (yet). Trying class Foo { void bar() {} const void bar() {} } gives me an error. I'm not sure if it is by design or just not working yet.Furthermore, is it possible to overload opApply(...) so it can be called on non-const objects and const objects, and the non-const variant has read-write access:Having that would pretty much depend on being able to have a opApply and a const opApply. I tried by using two functions with different names, but the compiler segfaulted on a ref const(Struct*). Cheers, Christian
Jul 25 2007
I may be wrong, but I think the idea is that a method either is or isn't const-safe, and the difference between const and mutable references to the object is supposed to be in the availability of methods, not in their behavior. While I'm sure there's some percentage of the time subtle behavioral changes could be desirable, I don't believe const-method overloading is meant to happen. That said, a few demonstrative cases sometimes do wonders. :)Well, the original poster basically wanted it to be possible to have class Container(T) { int opApply(int delegate(ref T) dg); const int opApply(int delegate(ref const(T)) dg); } such that foreach would work on const(Container!(T)) and Container!(T) alike, using the correct types. To me, that seems pretty reasonable. James Dennett pointed out another, simpler example Foo getThis() { return this; } const const(Foo) getThis() { return this; } invariant invariant(Foo) getThis() { return this; } Personally, I'd like to see the 'templating on const' solution that was thrown around during one of the const debates C C(Foo) getThis(constness C)() { return this; } and C int opApply(constness C)(int delegate(ref C(T)) dg) as the different versions are usually quite similar, except for slightly different types.(I'm also not 100% pleased with the 'const R M(){}' syntax for declaring const methods...Yes, it's quite bad: const Foo func(const Foo) { const Foo = ...; } All consts look the same, but the first means the method, the second is an alternative for const(Foo) and the third is the compile-time const storage class. I'd probably disallow const Foo in parameter declarations, yet don't know how to do make the method-const look different. Cheers, Christian
Jul 26 2007
Christian Kamm wrote:How about this for method-const: --- Foo const(func)(const Foo) { // ... } --- Though I guess that may look too much like the const(Type) notation...(I'm also not 100% pleased with the 'const R M(){}' syntax for declaring const methods...Yes, it's quite bad: const Foo func(const Foo) { const Foo = ...; } All consts look the same, but the first means the method, the second is an alternative for const(Foo) and the third is the compile-time const storage class. I'd probably disallow const Foo in parameter declarations, yet don't know how to do make the method-const look different.
Jul 26 2007
I thought the same thing: putting the const/invariant after the return type might be okay --- Foo const func(const(Foo)) --- but the current way of doing it has the merit of allowing --- const { void func1(); void func2(); } --- which'd be odd to explain with the const being anywhere but in the very front.I'd probably disallow const Foo in parameter declarations, yet don't know how to do make the method-const look different.How about this for method-const: --- Foo const(func)(const Foo) { // ... } --- Though I guess that may look too much like the const(Type) notation...
Jul 26 2007
Frits van Bommel wrote:Christian Kamm wrote:I have a radical notion. We could place it after the parameter list! Foo func(const Foo) const { // ... } -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.orgHow about this for method-const: --- Foo const(func)(const Foo) { // ... } --- Though I guess that may look too much like the const(Type) notation...(I'm also not 100% pleased with the 'const R M(){}' syntax for declaring const methods...Yes, it's quite bad: const Foo func(const Foo) { const Foo = ...; } All consts look the same, but the first means the method, the second is an alternative for const(Foo) and the third is the compile-time const storage class. I'd probably disallow const Foo in parameter declarations, yet don't know how to do make the method-const look different.
Jul 26 2007
Christian Kamm wrote:Well, the original poster basically wanted it to be possible to have class Container(T) { int opApply(int delegate(ref T) dg); const int opApply(int delegate(ref const(T)) dg); } such that foreach would work on const(Container!(T)) and Container!(T) alike, using the correct types. To me, that seems pretty reasonable.Initially I thought it would overload on the 'ref' part of the delegate in opApply, eg. class Container { int[] array; //called when 'ref' not used, suitable for 'const' objects int opApply(int delegate(int) dg) { int result = 0; for (int i = 0; i < array.length; i++) { result = dg(array[i]); if (result) break; } return result; } //called when 'ref' used, not suitable for 'const' objects int opApply(int delegate(ref int) dg) { int result = 0; for (int i = 0; i < array.length; i++) { result = dg(array[i]); if (result) break; } return result; } } Current D implementation expects the delegate to have 'ref' in it, anything else is an error and foreach on a const object gives: Error: a.opApply can only be called on a mutable object Instead it could, on a const object look for: int opApply(int delegate(Type) dg) and on non-const: int opApply(int delegate(ref Type) dg) Regan
Jul 26 2007