digitalmars.D.learn - const method and return type
- Andrea Fontana (15/15) Dec 13 2013 class A
- Adam D. Ruppe (5/13) Dec 13 2013 Inside getter, "this" is const. Due to transitive const, all the
- Andrea Fontana (24/40) Dec 13 2013 I read:
- Andrea Fontana (18/60) Dec 13 2013 Just another thought. If we have:
- Adam D. Ruppe (5/18) Dec 13 2013 Yes, in D, all members of a const object are const too. So inside
- Andrea Fontana (48/69) Dec 13 2013 Why? The object itself it's not a member. The reference to that
- Jakob Ovrum (5/6) Dec 13 2013 This isn't "escaping" constness. Const only means mutation is
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (4/16) Dec 14 2013 However, according to how D sees constness, mutating another_class
- Adam D. Ruppe (18/19) Dec 13 2013 Right, it is just that "auto" keeps the exact type, and in the
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (6/9) Dec 14 2013 Ah. I was about to respond by "that top level const is silly" but I now
- Jakob Ovrum (9/19) Dec 13 2013 `const` as a function attribute just marks the implicit
class A { auto getter() const { return property; } int property = 0; } Please notice that getter method is marked as const. Why this method return "const int"? If i force it declaring: int getter() const it returns "int". It takes me a lot to understand where the issue was in my code. Is it a bug?
Dec 13 2013
On Friday, 13 December 2013 at 23:46:14 UTC, Andrea Fontana wrote:class A { auto getter() const { return property; } int property = 0; Why this method return "const int"?Inside getter, "this" is const. Due to transitive const, all the members through this are const too. So inside getter, property is a const int. The auto return value returns the *exact* type, thus const.
Dec 13 2013
I read: Const Member Functions Const member functions are functions that are not allowed to change any part of the object through the member function's this reference. I'm not changing anything. Just returning it. Is this a try to avoid something like the following, then? ... B getter() const { return this.b; } ... void getter2() const { B var = getter(); var.non_const_method(); } I don't think it's the right way, is it? getter2() shouldn't be allowed becouse var is a reference to this.b, that's ok. But enforcing constness of return type IMHO is wrong. Something like: void main() { B value = myclass.getter(); b.non_const(); } seems correct to me. Also this seems correct: void getter2() /*non-const*/ { getter().non_const_method(); } On Saturday, 14 December 2013 at 00:01:31 UTC, Adam D. Ruppe wrote:On Friday, 13 December 2013 at 23:46:14 UTC, Andrea Fontana wrote:class A { auto getter() const { return property; } int property = 0; Why this method return "const int"?Inside getter, "this" is const. Due to transitive const, all the members through this are const too. So inside getter, property is a const int. The auto return value returns the *exact* type, thus const.
Dec 13 2013
Just another thought. If we have: class B; struct C; class A { void method() const { ... } B another_class; C a_struct; } B is just a reference to a object, so method() should not reassign it. The reference should be const, not the object itself. method() should be able to call mutable another_class methods. Am I wrong? Instead "a_struct" is not a reference, so method() should not edit it, this makes sense. You can return a copy or a const ref of a struct-member On Saturday, 14 December 2013 at 00:09:03 UTC, Andrea Fontana wrote:I read: Const Member Functions Const member functions are functions that are not allowed to change any part of the object through the member function's this reference. I'm not changing anything. Just returning it. Is this a try to avoid something like the following, then? ... B getter() const { return this.b; } ... void getter2() const { B var = getter(); var.non_const_method(); } I don't think it's the right way, is it? getter2() shouldn't be allowed becouse var is a reference to this.b, that's ok. But enforcing constness of return type IMHO is wrong. Something like: void main() { B value = myclass.getter(); b.non_const(); } seems correct to me. Also this seems correct: void getter2() /*non-const*/ { getter().non_const_method(); } On Saturday, 14 December 2013 at 00:01:31 UTC, Adam D. Ruppe wrote:On Friday, 13 December 2013 at 23:46:14 UTC, Andrea Fontana wrote:class A { auto getter() const { return property; } int property = 0; Why this method return "const int"?Inside getter, "this" is const. Due to transitive const, all the members through this are const too. So inside getter, property is a const int. The auto return value returns the *exact* type, thus const.
Dec 13 2013
On Saturday, 14 December 2013 at 00:24:01 UTC, Andrea Fontana wrote:Just another thought. If we have: class B; struct C; class A { void method() const { ... } B another_class; C a_struct; } B is just a reference to a object, so method() should not reassign it. The reference should be const, not the object itself. method() should be able to call mutable another_class methods. Am I wrong?Yes, in D, all members of a const object are const too. So inside method() const, another_class is const. Which means another_class.member is also const.
Dec 13 2013
On Saturday, 14 December 2013 at 00:31:24 UTC, Adam D. Ruppe wrote:On Saturday, 14 December 2013 at 00:24:01 UTC, Andrea Fontana wrote:Why? The object itself it's not a member. The reference to that object is the member. Consider this: class A {} class B { A first; A second; } void main() { auto a = new A; auto b = new B; b.first = a; b.second = a; assert(b.first == b.second); assert(&b.first == &b.second); } Second assert fail, of course. "first" and "second" are just two reference. They are different reference to the same object. Those reference should be const, not the object they refer. Consider this way to escape current constness: class A { int x; } A globalA; class B { void method() const { // first.x = 10; This doesn't work. But IMO it should globalA.x = 10; // This work. Same effect as preceding line writeln(first.x); // 10! } A first; A second; } void main() { globalA = new A; auto b = new B; b.first = globalA; b.second = globalA; b.method(); } You see?Just another thought. If we have: class B; struct C; class A { void method() const { ... } B another_class; C a_struct; } B is just a reference to a object, so method() should not reassign it. The reference should be const, not the object itself. method() should be able to call mutable another_class methods. Am I wrong?Yes, in D, all members of a const object are const too. So inside method() const, another_class is const. Which means another_class.member is also const.
Dec 13 2013
On Saturday, 14 December 2013 at 00:53:27 UTC, Andrea Fontana wrote:Consider this way to escape current constness:This isn't "escaping" constness. Const only means mutation is prevented through that particular reference. It is distinct from immutability.
Dec 13 2013
On 12/13/2013 04:24 PM, Andrea Fontana wrote:Just another thought. If we have: class B; struct C; class A { void method() const { ... } B another_class; C a_struct; } B is just a reference to a object, so method() should not reassign it. The reference should be const, not the object itself. method() should be able to call mutable another_class methods.However, according to how D sees constness, mutating another_class through its non-const methods would mutate the state of A as well. Ali
Dec 14 2013
On Saturday, 14 December 2013 at 00:09:03 UTC, Andrea Fontana wrote:I'm not changing anything. Just returning it.Right, it is just that "auto" keeps the exact type, and in the const method, the exact type of the members are all const too since that's how the language enforces that you don't change anything. You are allowed implicitly cast const(int) to int, which is why the version that specifically returns int works, it is just that auto doesn't do any implicit conversions. The same thing happens if you do const(int) a = 10; auto foo = a; foo = 0; // test500.d(5): Error: cannot modify const expression foo The auto var decl there keeps const too. There's some discussion that auto might strip off the top level const where it is otherwise allowed, but I'm not sure if that's actually going to happen or not.
Dec 13 2013
On 12/13/2013 04:30 PM, Adam D. Ruppe wrote:There's some discussion that auto might strip off the top level const where it is otherwise allowed, but I'm not sure if that's actually going to happen or not.Ah. I was about to respond by "that top level const is silly" but I now see that it is true only when no mutable reference is involved. So, in order to keep things simple, now I think that the current behavior is better. Ali
Dec 14 2013
On Friday, 13 December 2013 at 23:46:14 UTC, Andrea Fontana wrote:class A { auto getter() const { return property; } int property = 0; } Please notice that getter method is marked as const. Why this method return "const int"?`const` as a function attribute just marks the implicit this-reference parameter as const - apart from the necessary syntax deviation, it works like any other parameter. Thus, inside `getter`, `typeof(this)` is `const(A)`, and since const is transitive, that means `typeof(this.property)` is `const(int)`. If you explicitly specify the return type as `int`, then `property` is implicitly converted from `const(int)` to `int`, which is legal since `int` has no mutable indirection.
Dec 13 2013