问题
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?
回答1:
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).
回答2:
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.).
回答3:
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();
回答4:
Here's one way:
template <typename T>
T make_default()
{
return T();
}
int main()
{
int *p = make_default<int*>();
}
回答5:
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().
回答6:
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;
回答7:
This is how you do it int* ptr = new int;
Heap pointers
来源:https://stackoverflow.com/questions/8067568/how-do-i-value-initialize-a-type-pointer-using-type-like-syntax