In C++, object constructors cannot be const-qualified.
But - can the constructor of an object of class A
know whether it's constructing a const A
or a non-const A
?
Motivated by a fine point in the discussion regarding this question.
In C++, object constructors cannot be const-qualified.
But - can the constructor of an object of class A
know whether it's constructing a const A
or a non-const A
?
Motivated by a fine point in the discussion regarding this question.
Actually, a constructor never constructs a const object. The object is not const
during construction, in the sense that the constructor code is allowed to change the object. If you call methods from within the constructor - they will be the non-const variants of methods.
Thus, in this code:
struct A {
int foo() const { return 123; }
int foo() { return 456; }
A() { x = foo(); }
int x;
};
int bar() {
A a;
return a.x;
}
int baz() {
A const a;
return a.x;
}
both fnctions, bar()
and baz()
, return 456
- according to all major compilers (GodBolt).
What happens with the constructed object is simply not the constructor's business.
No, because copy elision (and the so-called guaranteed copy elision) can change the constness of an object "after" construction:
struct A {
bool c;
A() : c(magic_i_am_const()) {}
A(const A&)=delete; // immovable
};
const A f() {return {};}
A g() {return f();} // OK
void h() {
A x=f(); // OK
const A y=g(); // OK
}
What should x.c
and y.c
be?
x
and y
are created only once (by variable definition) and thus their constness doesn't change. –
Golly Actually, a constructor never constructs a const object. The object is not const
during construction, in the sense that the constructor code is allowed to change the object. If you call methods from within the constructor - they will be the non-const variants of methods.
Thus, in this code:
struct A {
int foo() const { return 123; }
int foo() { return 456; }
A() { x = foo(); }
int x;
};
int bar() {
A a;
return a.x;
}
int baz() {
A const a;
return a.x;
}
both fnctions, bar()
and baz()
, return 456
- according to all major compilers (GodBolt).
What happens with the constructed object is simply not the constructor's business.
© 2022 - 2025 — McMap. All rights reserved.
enum Tag { Mut, Const };
acceptable? So you'd doFoo foo{Mut};
orFoo const cfoo{Const};
... which means it's manual, and if someone messes up it'll be annoying to track down the mistake. – ContumelyFoo() const { ... }
constructor, then that would be the hook. So I think you'll need to cheat, or double-down cheat and use a MACRO. Or take a page out of JavaScript, and add afreeze()
method that sets a flag which is vetted for mutating methods and throws if tripped. – Contumely