6

I want to define something like

Map<int, char[5] > myMap;

The above declaration is accepted by c++ compiler and no error is thrown but when I do something like this

int main()
{
    char arr[5] ="sdf";
    map <int, char[5]> myMap;
    myMap.insert(pair<int, char[5]>(0,arr));
    return 0;
}

I get error as:

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

It is important for me to define a fixed size character array because it optimizes my network stream operation. Is there any way to achieve it? I do not want to use char * or std::string.

Deduplicator
  • 43,322
  • 6
  • 62
  • 109
Master Oogway
  • 401
  • 2
  • 5
  • 10
  • 1
    Have you tried defining a `struct` that contains a `char[5]`? – OmnipotentEntity Jul 16 '12 at 17:30
  • Why not `char *` or better yet `string`? –  Jul 16 '12 at 17:32
  • @OmnipotentEntity, yes I was able to do it by making it a struct :) But can you please explain me why did making it a struct work and not the char[5] itself ? – Master Oogway Jul 16 '12 at 17:38
  • @user - See this question [Why declare a struct that only contains an array](http://stackoverflow.com/questions/6966570/why-declare-a-struct-that-only-contains-an-array-in-c) – Bo Persson Jul 16 '12 at 17:53
  • 1
    Answers are great, but no one discussed why such a construct is not possible in c++, or if c++ compiler accepts the declaration, how to use it? Just from a theoretical point of view. – Sahil Singh Jun 06 '18 at 13:57

4 Answers4

9

I understand your performance requirements (since I do similar things too), but using character arrays in that way is rather unsafe.

If you have access to C++11 you could use std::array. Then you could define your map like:

map <int, array<char, 5>> myMap;

If you cannot use C++11, then you could use boost::array.

betabandido
  • 18,008
  • 10
  • 57
  • 72
2

One way is to wrap the fixed size character array as a struct.

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;
}
timrau
  • 22,054
  • 4
  • 51
  • 63
  • 2
    You are basically reimplementing a simpler version of std/boost array. This solution might be useful if the OP does not have access to C++11 nor boost, otherwise there is not need to reinvent the wheel. – betabandido Jul 16 '12 at 17:48
  • How to retrieve the data ? I used printf("%s\n", myMap[0].data) , but it does not work. – user3658306 Apr 28 '16 at 18:49
1

You cannot use an array in a standard container.

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

  2. Use a map of pointers to arrays of 5 elements.

  3. Use boost tuples instead of arrays of 5 elements.

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

\

struct ArrayMap
{
    int color[5];
};

/

-2

According to documentation pair can hold (and be defined for) distinct classes. C array is not a class, but a construct. You must define your own class with overloaded operator[](). Might need comparison operators as well

friendzis
  • 789
  • 6
  • 17
  • 2
    You only need to do comparisons on the `key_type`, not the `mapped_type` – Jonathan Wakely Jul 16 '12 at 17:36
  • Yes, in my case I needed the char array for the mapped type, therefore simply by making it a struct, it works for me. tyepdef struct { char arr[5]; } fixedArray; The above struct works for me. – Master Oogway Jul 16 '12 at 17:56