Символьный массив как значение в C++ map
Я хочу определить что-то вроде
Map<int, char[5] > myMap;
Вышеуказанное объявление принимается компилятором C++ и не выдает никакой ошибки, но когда я делаю что-то подобное
int main()
{
char arr[5] ="sdf";
map <int, char[5]> myMap;
myMap.insert(pair<int, char[5]>(0,arr));
return 0;
}
Я получаю ошибку как:
In file included from /usr/include/c++/4.6/bits/stl_algobase.h:65:0,
from /usr/include/c++/4.6/bits/char_traits.h:41,
from /usr/include/c++/4.6/ios:41,
from /usr/include/c++/4.6/ostream:40,
from /usr/include/c++/4.6/iostream:40,
from charMap.cpp:1:
/usr/include/c++/4.6/bits/stl_pair.h: In constructor ‘std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = int, _T2 = char [5]]’:
charMap.cpp:9:42: instantiated from here
/usr/include/c++/4.6/bits/stl_pair.h:104:31: error: array used as initializer
/usr/include/c++/4.6/bits/stl_pair.h: In constructor ‘std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) [with _U1 = int, _U2 = char [5], _T1 = const int, _T2 = char [5]]’:
charMap.cpp:9:43: instantiated from here
/usr/include/c++/4.6/bits/stl_pair.h:109:39: error: array used as initializer
Для меня важно определить массив символов фиксированного размера, потому что он оптимизирует работу моего сетевого потока. Есть ли способ добиться этого? Я не хочу использовать char *
или же std::string
,
6 ответов
Один из способов - обернуть массив символов фиксированного размера в структуру.
struct FiveChar
{
FiveChar(char in[5]) { memcpy(data, in, 5); }
char& operator[](unsigned int idx) { return data[idx]; }
char data[5];
};
int main(void)
{
char arr[5] = "sdf";
map<int, FiveChar> myMap;
myMap.insert(pair<int, FiveChar>(0, arr));
return 0;
}
Я понимаю ваши требования к производительности (так как я делаю аналогичные вещи тоже), но использование таким образом массивов символов небезопасно.
Если у вас есть доступ к C++11, вы можете использовать std::array
, Тогда вы можете определить свою карту как:
map <int, array<char, 5>> myMap;
Если вы не можете использовать C++11, то вы можете использовать boost::array
,
Вы не можете использовать массив в стандартном контейнере.
Используйте
std::vector
вместо массиваИспользуйте карту указателей на массивы из 5 элементов.
Используйте буст-кортежи вместо массивов из 5 элементов.
Вместо использования массива создайте новый
struct
это занимает 3 элемента. Сделатьmap<int, newstructtype>
, Или оберните ваш массив вstruct
и это тоже сработает.
\
struct ArrayMap
{
int color[5];
};
/
Вместо:
myMap.insert(pair<int, char[5]>(0,arr));
Заполните позицию следующим образом:
strncpy(myMap[0], arr, 5);
Предполагая, что цель состоит в том, чтобы упростить написание кода, используйте прием письма. Позвольте компилятору переназначить переменные указателям и целым числам: например, для широких и высоких переменных, таких как файл TIFF, попробуйте
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#define loc_wdth 30 /* location information on TIFF */
#define loc_hght 42 /* location information on TIFF */
main() {
uint32_t size;
unsigned char *buff = calloc( 200000, sizeof( char));
uint32_t *wide_o = (uint32_t *) &buff[ loc_wdth];
uint32_t *high_o = (uint32_t *) &buff[ loc_hght];
#define wide wide_o[ 0]
#define high high_o[ 0]
buff[ loc_wdth] = 2; /* reverse byte/bit order */
buff[ loc_hght] = 3;
printf("%x %x\n", buff[ loc_wdth], buff[ loc_hght]);
size = wide * high;
printf("w x h = %d x %d, size= %d\n", wide, high, size);
wide = 16000; /* > 255, 2 bytes */
high = 10000; /* > 255, 2 bytes */
size = wide * high; /* produces 4 byte result w/o
using uint32_t any more */
printf("w x h = %d x %d, size= %d\n", wide, high, size);
}
/*################## demo.c########################*/
Согласно документации, пара может содержать (и быть определена для) различных классов. Массив C - это не класс, а конструкция. Вы должны определить свой собственный класс с перегруженным operator[]()
, Возможно, понадобятся операторы сравнения