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

时间:2014-01-23 08:13:34

标签: c++ templates default-value

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

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。

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();