tags:

views:

190

answers:

6

Hi all,

Im trying to create a map, where the key is an int, and the value is an array

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

However, when I try to compile this code, I get the following error.

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

I really cant see where the error is. Or even if there's an error.

Any help (please include an explanation to help me avoid this mistake) will be appreciated.

Thanks in advance.

+1  A: 

You can't copy arrays by value like that.

Here are several solutions, but I recommend #4 for your needs:

1) Use an std::vector instead of an array

2) Use a map of pointers to arrays of 3 elements.

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) Use boost tuples instead of arrays of 3 elements.

4) Instead of using an array make a new struct that takes 3 elements. Make the map. Or wrap your array in a struct and that will work too.

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));
Brian R. Bondy
Thanks, nice alternative solution also.
Tom
about 3) This is a small project, cant add boost, but will take a look, thanks.
Tom
@Tom: Added a 4) which may be your easiest solution.
Brian R. Bondy
@Brian, Thanks, 4) Seems nicer.
Tom
use std::make_pair. See below.
Eddy Pronk
+2  A: 

Arrays are not first class constructs in C++. They are not Copy Constructible nor Assignable which are requirements for values of std::map. You can use boost::array or std::vector.

AraK
+1  A: 

Arrays cannot be the stored data in a standard container( std::pair)

aJ
+1  A: 

Another alternative is to put the arrays in a wrapping struct:

    struct Wrapper { int value[3]; };

    // ...
    Wrapper red = {{1,0,0}};    
    std::map<int,Wrapper> colours;    
    colours.insert(std::pair<int,Wrapper>(1, red));
Georg Fritzsche
A: 

use std::make_pair :

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::make_pair(GLUT_LEFT_BUTTON,&red));
colours.insert(std::make_pair(GLUT_MIDDLE_BUTTON,&blue));
colours.insert(std::make_pair(GLUT_RIGHT_BUTTON,&green));
Eddy Pronk
+1  A: 

Use 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));
missingfaktor