Variables of built-in types can be value-initialized like this:
int var = int();
this way I get the default value of int
without hardcoding the zero in my code.
However if I try to do similar stuff for a pointer:
int* ptr = int*();
the compiler (Visual C++ 10) refuses to compile that (says type int unexpected
).
How do I value-initialize a pointer in similar manner?
How do I value-initialize a Type* pointer using Type()-like syntax?
You cannot. The syntax T()
is defined in 5.2.3/1,2 (C++03, slightly different wording in C++11 FDIS). In particular the second paragraph states:
The expression T(), where T is a simple-type-specifier (7.1.5.2) for a non-array complete object type or the (possibly cv-qualified) void type, creates an rvalue of the specified type, which is value-initialized (8.5);
That means that int()
, will create an rvalue of type int and value-initialize it. Now the problem is that int*
is not a simple-type-specifier, but rather an elaborated-type-specifier. The definition of simple-type-specifier in the grammar is:
simple-type-specifier:
::opt nested-name-specifieropt type-name
::opt nested-name-specifier template template-id
char
wchar_t
bool
short
int
long
signed
unsigned
float
double
void
With type-name being defined as:
type-name:
class-name
enum-name
typedef-name
This is what makes the proposed solutions work. The creation of the typedef (either directly or through the template) creates a type-name (third type) that can be used as a simple-type-specifier (first type).
Use a typedef to make a name for your pointer type:
typedef int *ip;
ip ptr = ip();
The same idea should work for other types that require more than one lexical element (word) to define the name of the type (e.g., unsigned long
, long long
, unsigned long long *
, etc.).
Doesn't require the use of typedef
(but exclusive to C++11), which can be useful when dealing with several pointer types:
template<typename T>
using alias = T;
then alias<int*>
is int*
, so you can do int* p = alias<int*>()
.
A similar solution available to C++03, using an identity metafunction:
template<typename T>
struct identity {
typedef T type;
};
int* p = identity<int*>::type();
Here's one way:
template <typename T>
T make_default()
{
return T();
}
int main()
{
int *p = make_default<int*>();
}
Just do
int* x = int();
It still assigns 0 to the pointer making it point to the NULL address since you're defaulting it with the default value of int which is 0 anyway.
Actually, it works fine for all types:
double* y = int();
The address is still a 32-bit (or 64-bit depending on platform) integer so I think it should work fine for all types if you do = int().
The reason that doesn't work is because pointers do not have constructors.
The syntax
int ()
calls (in theory)
int::int ()
which initializes the variable. (More likely, the compiler just zeros the variable, but that's because it "knows" about ints).
In c++11, you can use nullptr
int *ptr = nullptr;
Otherwise, you pretty much have to use NULL:
int *ptr = NULL;
This is how you do it
int* ptr = new int;
Heap pointers