我有一个函数返回模板类型的默认构造值:
template<typename T>
T do_stuff()
{
return T();
}
我这样用:
int main(int argc, char** argv)
{
std::string str("hello");
int a = 10;
int *p = &a;
str = do_stuff<std::string>();
a = do_stuff<int>();
p = do_stuff<int*>();
return 0;
}
我使用它后:str
是一个空字符串,a
eqauls 0,p
是空指针。
我可以理解为什么std::string
变量变为空字符串(它具有构造空字符串的默认构造函数)。
但是为什么int
变量变为0并且指针变为空指针。
它是默认的模板行为吗?
我在Linux Centos下使用gcc 4.6.6。
答案 0 :(得分:18)
来自this reference on value initialization:
如果T是具有至少一个用户提供的任何类型构造函数的类类型,则调用默认构造函数。
如果T是不带任何用户提供的构造函数的非联合类类型,则该对象为零初始化,然后调用隐式声明的默认构造函数(除非它是微不足道的)
如果T是数组类型,则数组的每个元素都是值初始化的
否则,对象将进行零初始化。
发生的事情是上面列表中的最后一点。
答案 1 :(得分:10)
关键是
//------vv
return T();
例如,您可以测试以下内容,它是等效的:
int x = int();
std::cout << x;
在这种情况下, x
始终为0
。这同样适用于指针 - 它是零初始化的,“使它”NULL
。
这是值初始化,由括号“引起”。
答案 2 :(得分:6)
因为T()
是值初始化,int
和指针类型(以及其他基本类型)的初始化为零。
就像初始化int
你要做的那样:
int x{};
int x = int();
//not initialized:
int x; //if not at namespace scope
int x(); //method declaration
答案 3 :(得分:6)
这是在c ++ 11标准第8.5节中定义的:
对T类型的对象进行值初始化意味着:
- 如果T是具有用户声明的构造函数(12.1)的类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的); < / p>
- 如果T是没有用户声明的构造函数的非联合类类型,则T的每个非静态数据成员和基类组件都是值初始化的;
- 如果T是数组类型,则每个元素都是值初始化的;
- 否则,该对象为零初始化
和
默认初始化T类型的对象意味着:
- 如果T是非POD类类型(第9节),则调用T的默认构造函数(并且初始化为 如果T没有可访问的默认构造函数,则格式错误;
- 如果T是数组类型,则每个元素都是默认初始化的;
- 否则,该对象为零初始化。
和
零初始化T类型的对象意味着:
- 如果T是标量类型(3.9),则将对象设置为0(零)转换为T的值;
- 如果T是非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的;
- 如果T是联合类型,则对象的第一个命名数据成员89)是零初始化的;
- 如果T是数组类型,则每个元素都是零初始化的; - 如果T是引用类型,则不执行初始化。
答案 4 :(得分:4)
这是各种类型的正确行为,无处不在。
原始类型的初始化方式不同,具体取决于您是显式请求默认值(值初始化)还是不提及初始化(默认初始化)。
如果在不提及初始化的情况下构造基本类型(这称为默认初始化),则该值是随机的:
int x;
struct Y {
int x;
} x;
int *x = new int;
都是默认初始化,并且包含随机值。
但是如果你提到初始化器,它就会变成值初始化,并且值被初始化为适当的“零”(数字为0
,指针为0
/ nullptr
:
int x = 0;
int x = int();
struct Y {
int x;
Y() : x() {} // the x() is important
} y;
struct Z {
int x;
} z = {};
int *x = new int();
是所有值初始化,C ++ 11添加以下形式
int x{};
struct Y {
int x;
Y() : x{} {}
} y;
struct Z {
int x;
} z{};
int *x = new int{};
小心
int x(); // function, NOT A VARIABLE
它声明一个不带参数的函数并返回int
。这被称为“最令人烦恼的解析”。
答案 5 :(得分:3)
T()是值初始化。
使用:
int x{};
int x = int();