C++ 使用数组作为映射值:看不到错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2582529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:00:07  来源:igfitidea点击:

Using array as map value: can't see the error

c++arraysdictionary

提问by Tom

I'm 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 can't see where the error is. Or even if there's an error.

我真的看不出错误在哪里。或者即使有错误。

回答by Brian R. Bondy

You can't copy arrays by value like that.

你不能像这样按值复制数组。

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

这里有几种解决方案,但我建议 #4 满足您的需求:

1) Use an std::vectorinstead of an array

1) 使用一个std::vector代替数组

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

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

3) 使用boost 元组而不是 3 个元素的数组。

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.

4) 不使用数组,而是创建一个包含 3 个元素的新结构。制作地图。或者将您的数组包装在一个结构中,这也可以。

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

回答by AraK

Arrays are not first class constructs in C++. They are not Copy Constructiblenor Assignablewhich are requirements for values of std::map. You can use boost::arrayor std::vector.

数组不是 C++ 中的一流构造。它们不是Copy Constructible也不Assignable是 值的要求std::map。您可以使用boost::arraystd::vector

回答by missingfaktor

Use std::tr1::array.

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

Or std::arrayin C++11 and above

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

回答by Eric Leschinski

Don't map to an int[], instead, map to an int* like this:

不要映射到 int[],而是像这样映射到 int*:

#include <iostream>
#include <map>
using namespace std;
int main(){
    std::map<int,int*> colors;
    int red[] = {3,7,9};
    colors[52] = red;
    cout << colors[52][1];  //prints 7
    colors[52][1] = 11;
    cout << colors[52][1];  //prints 11
    return 0;
}

回答by Georg Fritzsche

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

回答by aJ.

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

数组不能是标准容器中存储的数据( std::pair)

回答by Merin Santhosh

Approach using structure in C++

在 C++ 中使用结构的方法

int MAX_DATA_PER_INSTR = 8;
//struct to hold the values. remember to write the constructor
struct InstrChar
{
  InstrChar(int in[MAX_DATA_PER_INSTR]) { 
    //c alternative is memcopy
    std::copy(in, in+MAX_DATA_PER_INSTR, data);
  }
  int data[MAX_DATA_PER_INSTR];
};

// create a key value pair 
std::map <int, InstrChar> address_instructions;
std::map <int, InstrChar>::iterator it;

// sample array, 8 elements
int xp[MAX_DATA_PER_INSTR ] = {31,4,3,4,4,3,1,2};
address_instructions.insert(std::pair<int, InstrChar>(PC, xp));
it = address_instructions.find(PC);
InstrChar buf1 = it->second;
//integer pointer to the array, can be dereferenced as *p, *(p+1), ....    //*(p+7)
int *p = buf1.data;

//in case you need to print these values out. They can also be referred to as buf1.data[0], buf1.data[1], buf1.data[2]
printf("%d\n", (*p));
printf("%d\n", *(p+1));
printf("%d\n", *(p+2));
printf("%d\n", *(p+3));
printf("%d\n", *(p+4));
printf("%d\n", *(p+5));
printf("%d\n", *(p+6));
printf("%d\n", *(p+7));