Thread overview
Bug? Const Class Makes Constructor Const
Oct 25, 2018
Vijay Nayar
Oct 25, 2018
Vijay Nayar
Oct 25, 2018
Vijay Nayar
October 25, 2018
void main()
{
  const class Bob {
    this() {
      bob = null;
    }
    Bob bob;
  }

  Bob b = new Bob();
}

Compiling this program gives the following error:

onlineapp.d(10): Error: constructor `onlineapp.main.Bob.this() const` is not callable using argument types `()`

I know that declaring a 'const class' adds 'const' to every member of the class, but does that even include constructors?  I'm not sure how one could use a class with a const constructor.  Is this a bug?
October 25, 2018
On 10/25/18 3:23 PM, Vijay Nayar wrote:
> void main()
> {
>    const class Bob {
>      this() {
>        bob = null;
>      }
>      Bob bob;
>    }
> 
>    Bob b = new Bob();
> }
> 
> Compiling this program gives the following error:
> 
> onlineapp.d(10): Error: constructor `onlineapp.main.Bob.this() const` is not callable using argument types `()`
> 
> I know that declaring a 'const class' adds 'const' to every member of the class, but does that even include constructors? I'm not sure how one could use a class with a const constructor. Is this a bug?

Generally:

const(Bob) /*or auto*/ b = new const(Bob)();

But the error message there looks really confusing to me.

-Steve
October 25, 2018
On Thursday, 25 October 2018 at 19:51:45 UTC, Steven Schveighoffer wrote:
> On 10/25/18 3:23 PM, Vijay Nayar wrote:
>> void main()
>> {
>>    const class Bob {
>>      this() {
>>        bob = null;
>>      }
>>      Bob bob;
>>    }
>> 
>>    Bob b = new Bob();
>> }
>> 
>> Compiling this program gives the following error:
>> 
>> onlineapp.d(10): Error: constructor `onlineapp.main.Bob.this() const` is not callable using argument types `()`
>> 
>> I know that declaring a 'const class' adds 'const' to every member of the class, but does that even include constructors? I'm not sure how one could use a class with a const constructor. Is this a bug?
>
> Generally:
>
> const(Bob) /*or auto*/ b = new const(Bob)();
>
> But the error message there looks really confusing to me.
>
> -Steve

Yeah it's a bit odd.  The error message isn't super clear, the only reason I think it's because "const" is applying to the constructor, is because I get the same error by manually applying const to all members like below.

void main()
{
  class Bob {
    this() const {
      bob = null;
    }
    const Bob bob;
  }

  auto b = new Bob();
}

But if the "this() const {" is changed to "this() {", then the error goes away.
October 25, 2018
On 10/25/18 4:14 PM, Vijay Nayar wrote:
> On Thursday, 25 October 2018 at 19:51:45 UTC, Steven Schveighoffer wrote:
>> On 10/25/18 3:23 PM, Vijay Nayar wrote:
>>> void main()
>>> {
>>>    const class Bob {
>>>      this() {
>>>        bob = null;
>>>      }
>>>      Bob bob;
>>>    }
>>>
>>>    Bob b = new Bob();
>>> }
>>>
>>> Compiling this program gives the following error:
>>>
>>> onlineapp.d(10): Error: constructor `onlineapp.main.Bob.this() const` is not callable using argument types `()`
>>>
>>> I know that declaring a 'const class' adds 'const' to every member of the class, but does that even include constructors? I'm not sure how one could use a class with a const constructor. Is this a bug?
>>
>> Generally:
>>
>> const(Bob) /*or auto*/ b = new const(Bob)();
>>
>> But the error message there looks really confusing to me.
>>
> 
> Yeah it's a bit odd.  The error message isn't super clear, the only reason I think it's because "const" is applying to the constructor, is because I get the same error by manually applying const to all members like below.
> 
> void main()
> {
>    class Bob {
>      this() const {
>        bob = null;
>      }
>      const Bob bob;
>    }
> 
>    auto b = new Bob();
> }
> 
> But if the "this() const {" is changed to "this() {", then the error goes away.

No, I mean the correct way to construct an object with a const constructor is `new const(Bob)`. The error message seems to suggest you just aren't calling it with the right parameters, but subtly it is conveying the error:

Error: constructor `onlineapp.main.Bob.this() const` is not callable using argument types `()`

See, you should be calling it with argument types `() const`, but you are using `()`.

It's a terrible way to say "you can only call this on a const object", but constructors are special, so I think a special error message should be used.

To answer your other question -- yes it is correct that const is applying to the constructor when you apply it to the type.

-Steve
October 25, 2018
On Thursday, 25 October 2018 at 20:27:43 UTC, Steven Schveighoffer wrote:
>
> See, you should be calling it with argument types `() const`, but you are using `()`.
>
> It's a terrible way to say "you can only call this on a const object", but constructors are special, so I think a special error message should be used.
>
> To answer your other question -- yes it is correct that const is applying to the constructor when you apply it to the type.
>
> -Steve

Oh, I see now.
  auto b = new const(Bob)();

I suppose const(Bob) is a type in this case.  I guess I'm not sure what the purpose of having a const constructor is. I see the benefit of having const members, to assure that the object is not modifed after creation, but when the constructor is const as well, that enforces head-const behavior as well, so that whenever a reference variable is initialized, that it cannot later reference something else.

Maybe it's just best that I avoid this feature and don't put const in front of the class.
October 25, 2018
On 10/25/18 4:39 PM, Vijay Nayar wrote:
> I suppose const(Bob) is a type in this case.  I guess I'm not sure what the purpose of having a const constructor is. 

The main purpose is if you have const members that have to be assigned from const data.

For example:

class C
{
   int *ptr;
   this(int *p) { ptr = p; }
}

If you want to construct a const(C) with a const(int)*, you need a const constructor:

this(const(int *)p) const { ptr = p; }

I don't see how else you would do it.

> I see the benefit of having const members, to assure that the object is not modifed after creation, but when the constructor is const as well, that enforces head-const behavior as well, so that whenever a reference variable is initialized, that it cannot later reference something else.

Then you want a class that has tail-const data, not a const class.

> Maybe it's just best that I avoid this feature and don't put const in front of the class.

Yeah, a const class is existentially unchangable after construction.

-Steve