Используя массив как значение карты: не видьте ошибку

Я пытаюсь создать карту, где ключ является интервалом, и значение является массивом

int red[3]  = {1,0,0};
int green[3] = {0,1,0};
int blue[3]     = {0,0,1};

    std::map<int, int[3]> colours;

colours.insert(std::pair<int,int[3]>(GLUT_LEFT_BUTTON,red)); //THIS IS LINE 24 !
colours.insert(std::pair<int,int[3]>(GLUT_MIDDLE_BUTTON,blue));
colours.insert(std::pair<int,int[3]>(GLUT_RIGHT_BUTTON,green));

Однако, когда я пытаюсь скомпилировать этот код, я получаю следующую ошибку.

g++ (Ubuntu 4.4.1-4ubuntu8) 4.4.1

 In file included from /usr/include/c++/4.4/bits/stl_algobase.h:66,
                 from /usr/include/c++/4.4/bits/stl_tree.h:62,
                 from /usr/include/c++/4.4/map:60,
                 from ../src/utils.cpp:9:
/usr/include/c++/4.4/bits/stl_pair.h: In constructor ‘std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = int, _T2 = int [3]]’:
../src/utils.cpp:24:   instantiated from here
/usr/include/c++/4.4/bits/stl_pair.h:84: error: array used as initializer
/usr/include/c++/4.4/bits/stl_pair.h: In constructor ‘std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) [with _U1 = int, _U2 = int [3], _T1 = const int, _T2 = int [3]]’:
../src/utils.cpp:24:   instantiated from here
/usr/include/c++/4.4/bits/stl_pair.h:101: error: array used as initializer
In file included from /usr/include/c++/4.4/map:61,
                 from ../src/utils.cpp:9:
/usr/include/c++/4.4/bits/stl_map.h: In member function ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = int [3], _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int [3]> >]’:
../src/utils.cpp:30:   instantiated from here
/usr/include/c++/4.4/bits/stl_map.h:450: error: conversion from ‘int’ to non-scalar type ‘int [3]’ requested
make: *** [src/utils.o] Error 1

Я действительно не вижу, где ошибка. Или даже если существует ошибка.

25
задан halfer 3 November 2017 в 12:21
поделиться

5 ответов

Вы не можете копировать массивы по значению таким образом.

Вот несколько решений, но я рекомендую #4 для ваших нужд:

1) Использовать std::vector вместо массива

2) Использовать карту указателей на массивы из 3 элементов.

int red[3]  = {1,0,0};
int green[3] = {0,1,0};
int blue[3]     = {0,0,1};
std::map<int,int(*)[3]> colours;
colours.insert(std::pair<int,int(*)[3]>(GLUT_LEFT_BUTTON,&red));
colours.insert(std::pair<int,int(*)[3]>(GLUT_MIDDLE_BUTTON,&blue));
colours.insert(std::pair<int,int(*)[3]>(GLUT_RIGHT_BUTTON,&green));
//Watch out for scope here, you may need to create the arrays on the heap.

3) Использовать boost tuples вместо массивов из 3 элементов.

4) Вместо массива сделайте новую структуру, принимающую 3 элемента. Создайте карту. Или оберните ваш массив в struct, и это тоже будет работать.

struct Triple
{
    int color[3];
};

 //Later in code
Tripple red = {1, 0, 0}, green = {0, 1, 0}, blue = {0, 0, 1};
std::map<int,Triple> colours;
colours.insert(std::pair<int,Triple>(GLUT_LEFT_BUTTON,red));
colours.insert(std::pair<int,Triple>(GLUT_MIDDLE_BUTTON,blue));
colours.insert(std::pair<int,Triple>(GLUT_RIGHT_BUTTON,green));
41
ответ дан 28 November 2019 в 18:19
поделиться

Другой альтернативой является размещение массивов в структуре-оболочке:

    struct Wrapper { int value[3]; };

    // ...
    Wrapper red = {{1,0,0}};    
    std::map<int,Wrapper> colours;    
    colours.insert(std::pair<int,Wrapper>(1, red));
3
ответ дан 28 November 2019 в 18:19
поделиться

Массивы не могут быть данными, хранящимися в стандартном контейнере ( std :: pair )

1
ответ дан 28 November 2019 в 18:19
поделиться

В C ++ массивы не являются конструкциями первого класса. Они не являются ни Copy Constructible , ни Assignable , которые являются требованиями для значений std :: map . Вы можете использовать boost :: array или std :: vector .

7
ответ дан 28 November 2019 в 18:19
поделиться

Используйте std :: tr1 :: array .

typedef std::tr1::array<int, 3> Triple;
Triple red   = {1, 0, 0};
Triple green = {0, 1, 0};
Triple blue  = {0, 0, 1};
std::map<int, Triple> colours;
colours.insert(std::make_pair(GLUT_LEFT_BUTTON,   red));
colours.insert(std::make_pair(GLUT_MIDDLE_BUTTON, blue));
colours.insert(std::make_pair(GLUT_RIGHT_BUTTON,  green));

Или std :: array в C ++ 11 и выше

using  Triple = std::array<int, 3>; 
Triple red   = {1, 0, 0};
Triple green = {0, 1, 0};
Triple blue  = {0, 0, 1};
std::map<int, Triple> colours;
colours.insert(std::make_pair(GLUT_LEFT_BUTTON,   red));
colours.insert(std::make_pair(GLUT_MIDDLE_BUTTON, blue));
colours.insert(std::make_pair(GLUT_RIGHT_BUTTON,  green));
6
ответ дан 28 November 2019 в 18:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: