如何确保在 C++ 中的 Class 模板中正确初始化非静态数据成员

How to Ensure proper initialization of Non Static Data Members within a Class Template in C++

我正在使用 C++ 中的模板,想知道我们如何正确(值)初始化 class 模板中的非静态数据成员。例如,考虑以下片段:

template<typename T>
class MyVector
{
    T x; // x has undefined value for a built in type
};

现在我知道数据成员 x 对于 local/block 范围内的内置类型具有 垃圾值 除非显式初始化。

所以我想对数据成员进行值初始化。如果我将上面的代码修改为:

template<typename T>
class MyVector
{
    T x(); // now x becomes a member function 
};

从上面修改后的代码片段可以看出,x现在是一个成员函数。我如何 value 初始化 类型 T 的数据成员 x

您可以使用 default member initializer (C++11 起),它只支持等号或大括号初始化器,但不支持圆括号。

template<typename T>
class MyVector
{
    T x{};
    // or
    T x = T();
};

或者提供一个带有成员初始值设定项列表的用户定义的构造函数。

template<typename T>
class MyVector
{
    T x;
    MyVector() : x() {}
};

根据您使用的 C++ 版本,有不同的方法可以完成您想要的操作。这在下面有更详细的解释:

C++11

template<typename T>
class MyVector
{
    T x{}; 
};

C++11 之前

template<typename T>
class MyVector
{
    T x;
    MyVector(): x()
    {
    }
};

C++11

从 C++11 开始,您还可以编写(使用 构造函数初始化列表):

template<typename T>
class MyVector
{
    T x;
    MyVector(): x{}
    {
    }
};

C++11

请注意,此版本 won't work if 用于复制初始化的构造函数是 显式 因为没有强制性的 copy elison

#include <iostream>

using namespace std;
struct Name 
{
    explicit Name(const Name&)
  {
      
  }
  Name() = default;
};
template<typename T>
class MyVector
{
    public:
    T x = T();
    
};
int main()
{
    cout<<"Hello World";
    MyVector<int> p; // works with C++11,C++17 etc
    MyVector<Name> n; //error with C++11 and C++14
    return 0;
}

但是上面的版本will work用C++17因为在C++17中有强制复制elison

#include <iostream>

using namespace std;
struct Name 
{
    explicit Name(const Name&)
  {
      
  }
  Name() = default;
};
template<typename T>
class MyVector
{
    public:
    T x = T();
    
};
int main()
{
    cout<<"Hello World";
    MyVector<int> p; // works with C++11,C++17 etc
    MyVector<Name> n; //works with C++17 due to mandatory copy elison
    return 0;
}