返回默认构造值的模板函数

han*_*ank 13 c++ templates default-value

我有一个函数返回模板类型的默认构造值:

template<typename T>
T do_stuff()
{
    return T();
}
Run Code Online (Sandbox Code Playgroud)

我这样使用它:

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;
}
Run Code Online (Sandbox Code Playgroud)

我使用它后,我有:str是一个空字符串,aeqauls 0并且p是一个空指针.我可以理解为什么std::string变量变成空字符串(它具有构造空字符串的默认构造函数).但是为什么int变量变为0并且指针变为空指针.它是默认模板行为吗?

我在Linux Centos下使用gcc 4.6.6.

Som*_*ude 18

这个值初始化的参考:

  • 如果T是具有至少一个用户提供的任何类型构造函数的类类型,则调用默认构造函数.

  • 如果T是没有任何用户提供的构造函数的非联合类类型,则该对象被零初始化,然后调用隐式声明的默认构造函数(除非它是微不足道的)

  • 如果T是数组类型,则数组的每个元素都是值初始化的

  • 否则,该对象是零初始化的.

发生的事情是上面列表中的最后一点.


Kir*_*rov 10

关键在于

//------vv
return T();
Run Code Online (Sandbox Code Playgroud)

例如,您可以测试以下内容,它们是等效的:

int x =  int();
std::cout << x;
Run Code Online (Sandbox Code Playgroud)

x永远都是0这种情况.这同样适用于指针 - 它是零初始化的,"制造"它NULL.

这是值初始化,由括号"引起".


Luc*_*ore 6

因为T()是值初始化,其中int和指针类型(和其他基本类型)是零初始化.

就像值初始化int你做的那样:

int x{};
int x = int();

//not initialized:
int x;   //if not at namespace scope
int x(); //method declaration
Run Code Online (Sandbox Code Playgroud)


tum*_*dum 6

这是在c ++ 11标准第8.5节中定义的:

对值类型T的对象进行值初始化意味着:

- 如果T是具有用户声明的构造函数(12.1)的类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);

- 如果T是没有用户声明的构造函数的非联合类类型,则T的每个非静态数据成员和基类组件都是值初始化的;

- 如果T是数组类型,则每个元素都是值初始化的;

- 否则,对象被零初始化

和:

默认初始化T类型的对象意味着:

- 如果T是非POD类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);

- 如果T是数组类型,则每个元素都是默认初始化的;

- 否则,对象被零初始化.

和:

零初始化T类型的对象意味着:

- 如果T是标量类型(3.9),则将对象设置为0(零)转换为T的值;

- 如果T是非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的;

- 如果T是联合类型,则对象的第一个命名数据成员89)是零初始化的;

- 如果T是数组类型,则每个元素都是零初始化的; - 如果T是引用类型,则不执行初始化.