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

问题描述 投票:0回答:2

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

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

现在我知道数据成员

x
对于本地/块范围内的内置类型具有垃圾值,除非显式初始化。

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

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

从上面修改后的代码片段中可以看出,

x
现在是一个成员函数。我如何值初始化类型
x
的数据成员
T

c++ c++11 templates initialization c++17
2个回答
3
投票

您可以使用 默认成员初始值设定项 (C++11 起),它仅支持等号或大括号初始值设定项,但不支持括号。

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

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

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

2
投票

根据您使用的 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

请注意,如果用于复制初始化的构造函数是显式,则此版本将无法工作,因为没有强制的复制省略

#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;
}

但是上述版本将适用于 C++17,因为 C++17 中存在强制复制省略

#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 and following MyVector<Name> n; //works with C++17 due to mandatory copy elision return 0; }
    
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.