I have a custom class that I want to behave like a built-in type.
However I have noticed that you can initialise a const variable of that class without providing an initial value. My class currently has an empty default constructor.
Here is a comparison of int and my class foo:
int a; // Valid
int a = 1; // Valid
const int a = 1; // Valid
const int a; // Error
foo a; // Valid
foo a = 1; // Valid
const foo a = 1; // Valid
const foo a; // Should cause an error, but it compiles
As you can see I need to prevent
const foo a;
from compiling.
Any ideas from C++ gurus?
It compiles only if it has a default constructor, and it compiles because it has it, which means that it is initialized. If you don't want that line to compile, just disable the default constructor (will also make foo a;
an error as an unwanted side effect). Without a definition of foo
or what you want to do, this is as far as I can get.
I don't think there is any way of achieving what you want (i.e. allow the non-const variable to be default initialized, while having the const version fail compilation and allowing the other use cases --that require providing constructors)
The rules of C++ simply say that default-initialization (e.g. new T;
) and value-initialization (e.g. new T();
) are the same for objects of class type, but not for objects of fundamental type.
There's nothing you can do to "override" this distinction. It's a fundamental part of the grammar. If your class is value-initializable, then it is also default-initializable.
There is a sort-of exception for classes without any user-defined constructors: In that case, initialization of members is done recursively (so if you default-init the object, it tries to default-init all members), and this will fail if any of the class members are themselves fundamental, or again of this nature.
For example, consider the following two classes:
struct Foo { int a; int b; };
struct Goo { int a; int b; Goo(){} };
//const Foo x; // error
const Goo y; // OK
The implicit constructor for Foo
is rejected because it doesn't initialize the fundamental members. However, y
is happily default-initialized, and y.a
and y.b
are now "intentionally left blank".
But unless your class doesn't have any user-defined constructors, this information won't help you. You cannot "forward" the initialization type to a member (like ).Foo() : INIT_SAME_AS_SELF(a), b() { }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With