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

Time:12-25

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?

CodePudding user response:

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

CodePudding user response:

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

  • Related