www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - D2.0 const this methods

reply Bill Baxter <dnewsgroup billbaxter.com> writes:
 From the const page docs
class Foo {
    invariant int foo() {
       ...
    }
}

makes 'this' and the return value invariant.

But it give a syntax example for const methods.  So is it just 'const' 
instead of 'invariant'?

class Foo {
    const int foo() {
       this.value = 10; // error -- this is const
       return this.value;
    }
}

So what if I want to make a method that returns a const ptr/ref but 
modifies 'this'?

--bb
Jun 18 2007
next sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
This seems to work:

class Foo
{
    int x;

    const(Foo) getThis()
    {
        x = 42;
        return cast(const)this;
    }
}

Remember that "const Foo" is actually "const const(Foo)": a *constant
reference* to a constant Foo.  What you want is a plain old constant
Foo: const(Foo).

Your example is bad because "const int" by itself only really makes
sense as a declaration, not a return type: you're returning a const(int)
which doesn't do anything.

Does that help?

	-- Daniel
Jun 18 2007
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Bill Baxter wrote:
  From the const page docs
 class Foo {
    invariant int foo() {
       ...
    }
 }
 
 makes 'this' and the return value invariant.

No. invariant as a storage class on a member function only makes the member function invariant, it does not affect the return type.
 So what if I want to make a method that returns a const ptr/ref but 
 modifies 'this'?

const(int)* foo() { ... }
Jun 18 2007
parent reply Georg Wrede <georg nospam.org> writes:
Walter Bright wrote:
 Bill Baxter wrote:
 
  From the const page docs
 class Foo {
    invariant int foo() {
       ...
    }
 }

 makes 'this' and the return value invariant.

No. invariant as a storage class on a member function only makes the member function invariant, it does not affect the return type.

Am I the only one who thinks it is hard to remember that a word (here 'invariant') somewhere applies on this and otherwise on that? Should we have the keywords applying to the function be written after the function signature, and those applying to the return type before it? (I'd really hate D to become another language where one has to remember a truckload of stuff by heart.)
Jun 18 2007
next sibling parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Georg Wrede wrote:
 Walter Bright wrote:
 Bill Baxter wrote:

  From the const page docs
 class Foo {
    invariant int foo() {
       ...
    }
 }

 makes 'this' and the return value invariant.

No. invariant as a storage class on a member function only makes the member function invariant, it does not affect the return type.

Am I the only one who thinks it is hard to remember that a word (here 'invariant') somewhere applies on this and otherwise on that? Should we have the keywords applying to the function be written after the function signature, and those applying to the return type before it? (I'd really hate D to become another language where one has to remember a truckload of stuff by heart.)

As much as I hate to admit this... I would personally prefer the const|invariant occuring after the signature as well. It shames me, truly it does! But it /is/ less ambiguous than this, where it becomes difficult to quickly discern with the eyes whether the method is const|invariant, or whether the return type is. (Yes, technically, there would be parentheses to disambiguate if it were the type... but then again, I'd bet forgetting those paren's would lead to interesting new bugs, and that's precisely the sort of thing these are supposed to help prevent!) -- Chris Nicholson-Sauls
Jun 20 2007
prev sibling parent Walter Bright <newshound1 digitalmars.com> writes:
Georg Wrede wrote:
 Walter Bright wrote:
 Bill Baxter wrote:

  From the const page docs
 class Foo {
    invariant int foo() {
       ...
    }
 }

 makes 'this' and the return value invariant.

No. invariant as a storage class on a member function only makes the member function invariant, it does not affect the return type.

Am I the only one who thinks it is hard to remember that a word (here 'invariant') somewhere applies on this and otherwise on that? Should we have the keywords applying to the function be written after the function signature, and those applying to the return type before it? (I'd really hate D to become another language where one has to remember a truckload of stuff by heart.)

Think of it this way - const as a storage class applies to the top level of the type being declared, and everything that type refers to. For a member function declaration, then, the const would apply to the member function, as that is the top level. Having const work this way also allows one to group the const member function declarations like: class Foo { const { int foo(); int bar(); } } I think it'll be easier to recognize const member functions, because I personally find it hard to find the trailing const in a complex declaration.
Jun 20 2007