std::unordered_map constructor with initializer_list and size compiles in main, but not in class definition
Asked Answered
H

1

5

I am trying to initialize an std::unordered_map using the constructor that accepts data through an initialization list and the initial number of buckets.

For some reason, that constructor works if I put it in main, but has a syntax error when I put it in a class header.

Specifically, the header, called momo.h:

#pragma once
#include <unordered_map>

namespace std 
{
   template <>
   struct hash<std::pair<uint16_t, uint16_t>>
   {
      std::size_t operator()(const std::pair<uint16_t, uint16_t>& k) const
      {
         return (std::hash<long>()((((long)k.first) << 16) + (long)k.second));
      }
   };
}

class test
{
   std::unordered_map<std::pair<uint16_t, uint16_t>, uint16_t> m_Z(
      { /* Fails here: syntax error: missing ')' before '{' */
          {std::pair{ 1, 2 }, 3},
          {std::pair{ 4, 5 }, 6}
      }, 128);

};

While if I remove the definition from the header into main thus:

#include "Momo.h"

int main()
{
   test X;

   std::unordered_map<std::pair<uint16_t, uint16_t>, uint16_t> Y(
      {
          {std::pair{ 1, 2 }, 3},
          {std::pair{ 4, 5 }, 6}
      }, 128);
}

The code compiles without error. Why?

Haleyhalf answered 27/10, 2019 at 8:9 Comment(0)
D
10

You need to braced-init-list(or uniform-initiation) the std::unordered_map in the class.

class test
{
   std::unordered_map<std::pair<uint16_t, uint16_t>, uint16_t> m_Z{ // >> brased init
      { 
           {std::pair{ 1, 2 }, 3},
           {std::pair{ 4, 5 }, 6}
      }, 128 
   }; // >>>

};
Desrosiers answered 27/10, 2019 at 8:14 Comment(2)
This works for me (will mark it as an answer in a few minutes, when the site allows me), which raises the question why?Haleyhalf
@UriRaz That is the only way(or also with map ={}) you can initialize it in the class definition. Read More:blog.quasardb.net/2017/03/05/cpp-braced-initializationDesrosiers

© 2022 - 2024 — McMap. All rights reserved.