www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Bug? Const Class Makes Constructor Const

reply Vijay Nayar <madric gmail.com> writes:
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?
Oct 25 2018
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Oct 25 2018
parent reply Vijay Nayar <madric gmail.com> writes:
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.
Oct 25 2018
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Oct 25 2018
parent reply Vijay Nayar <madric gmail.com> writes:
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.
Oct 25 2018
parent Steven Schveighoffer <schveiguy gmail.com> writes:
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
Oct 25 2018