3

I have an unordered map that has a key of an int and a value of a struct. If the key is not found, I want the map to create a zero initialized struct.

struct TestStruct
{ 
   int a;
};

void foo()
{
   std::unordered_map<int, TestStruct> map;
   TestStruct& test = map[1];    
}

When debugging I can see that the values of test.a == 0 but is this a coincidence?

Relevant post: Does a c++ struct have a default constructor?

David
  • 87
  • 1
  • 11

1 Answers1

8

No, it's not coincidence, and yes, the map creates a zero-initialized struct. But let's go through the details:

New elements in the map are created with value-initialization; essentially with something like ::new (address) T(). Value-initialization of a class without user-defined default constructor such as your TestStruct means that the object is zero-intialized, hence all non-static members are zero-initialized.

From [dcl.init]p8:

To value-initialize an object of type T means: [...] if T is a [...] class type without a user-provided or deleted default constructor, then the object is zero-initialized [...]

From [dcl.init]p6:

To zero-initialize an object or reference of type T means: [...] if T is a [...] class type, its padding bits (6.7) are initialized to zero bits and each non-static data member, each non-virtual base class subobject, and, if the object is not a base class subobject, each virtual base class subobject is zero-initialized [...]

But if your class had a user-defined default constructor, then value-initialization would result in that constructor being called. So it's true that your int is zero-intitialized, but only because of the particularly simple kind of class you have.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084