[Solved] How to construct and initialize an array in place ?

Hi,

Is it possible to construct an array in place as a value argument for unordered_map?

I've tried a lot of things, including:
1
2
  std::unordered_map<std::string, int*> lMap;
  lMap.insert({"dupa", ((new int[]){1,2,3,4})});


can't get it to work.

Thanks for help.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// unordered_map::insert
#include <iostream>
#include <string>
#include <unordered_map>

int main ()
{
  std::unordered_map<std::string,int*> myrecipe;

  myrecipe.insert( {"sugar", new int[3] {2, 4, 7} } );

  std::cout << "myrecipe contains:" << std::endl;
  for (auto& x: myrecipe)
    std::cout << x.first << ": " << x.second[2] << std::endl;

  std::cout << std::endl;
  return 0;
}

myrecipe contains:
sugar: 7

If I leave out the size of the array, then:
 In function 'int main()':
10:38: error: expected primary-expression before ']' token
10:48: error: too many initializers for 'int [1]'

The same error occurs with plain:
auto p = new int[] {2, 4, 7};

In other words one can initialize the dynamically allocated array in C++11, but compiler does not deduce the size of the array from the initializer like it does for static allocation.
Strongly consider using std::vector<int> as the mapped_type
For example:

1
2
3
4
5
6
7
8
9
10
11
#include <vector>
#include <string>
#include <unordered_map>

int main()
{
    std::unordered_map< std::string, std::vector<int> > lMap { { "milk", { 0, 1, 2 } }, { "cream", { 5, 6, 7, 8 } } };
    lMap.emplace( "sugar", std::vector<int>{ 9, 10, 11, 12, 13 } ) ;
    lMap[ "coffee" ] = { 14, 15, 16, 17, 18, 19, 20 } ;
    // ...
}
Thank you for taking your time and answering this!
Hi again,

I've tried with enum type and it does not work. What am I doing wrong? Example:

1
2
3
4
5
6
7
8
9
enum class SettingState {Enabled, Disabled, Unavailable};

class PaintSettings
{
private:
    std::unordered_map<std::string, SettingState*> m_objectSettings = {
        {"test", new SettingState[4]{SettingState::Enabled, SettingState::Enabled, SettingState::Enabled, SettingState::Unavailable}}
    };
};


Reason: cannot convert from 'initializer list' to 'std::pair<const _Kty,_Ty>'
with
[
_Kty=std::string,
_Ty=SettingState *
]
works for me as you wrote it. You probably just forgot to include <unordered_map> , which pulls in utility with all the pair stuff.

Full example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <string>
#include <unordered_map>

using std::cout;
using std::endl;

enum class SettingState {Enabled, Disabled, Unavailable};

std::ostream& operator<<(std::ostream& os, const SettingState& s)
{
    if (s == SettingState::Enabled)
        os << "Enabled";
    else if (s == SettingState::Disabled)
        os << "Disabled";
    else
        os << "Unavailable";
    return os;
}


class PaintSettings
{
public:
    PaintSettings()
    {
        object_settings_ = 
        {
            {"test", new SettingState[4]{SettingState::Enabled, SettingState::Enabled, SettingState::Enabled, SettingState::Unavailable}}
        };
    }

    const std::unordered_map<std::string, SettingState*>& ObjectSettings()
    {
        return object_settings_;
    }
private:
    std::unordered_map<std::string, SettingState*> object_settings_; 
};

int main() 
{
    PaintSettings p;
    for (auto& s : p.ObjectSettings())
    {
        cout << s.first << ": [";
        for (int i=0; i<4; ++i)
            cout << s.second[i] << " ";
        cout << "]" << endl;
    }
}


test: [Enabled Enabled Enabled Unavailable ]
Thank you for testing this out. Now it works, maybe Qt was playing tricks on me, this IDE sometimes behaves strangely...
Topic archived. No new replies allowed.