2

I am working with templates in C++ and want to know how can we properly(value) initialize the non static data members in a class template. For example, consider the following snippet:

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

Now i know that the data member x has garbage value for built in types in local/block scope unless explicitly initialized.

So i want to value initialize the data member. If i modify the above code to:

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

As can be seen in the above modified code snippet, x is now a member function. How can i value initialize the data member x for type T?

2 Answers2

3

You can use default member initializer (since C++11), which only supports equal-sign or braced initializer, but not parentheses one.

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

Or provide a user-defined constructor with member initializer list.

template<typename T>
class MyVector
{
    T x;
    MyVector() : x() {}
};
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
2

There are different way to do what you want depending upon which C++ version you're using. This is explained in more detail below:

C++11

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

Pre C++11

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

C++11

From C++11 and onwards, you can also write(using constructor initializer list):

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

C++11

Note that this version won't work if the constructor for copy initialization is explicit since there is no mandatory 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;
}

But the above version will work with C++17 since there is mandatory copy elison in 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 etc
    MyVector<Name> n; //works with C++17 due to mandatory copy elison
    return 0;
}

Jason
  • 36,170
  • 5
  • 26
  • 60