Marcus McLean
Marcus McLean

Reputation: 1326

C-style array in C++ map

Note: this question is only about maps and arrays in C++. It only so happens that I'm using OpenGL, so those without OpenGL knowledge should not be discouraged from reading further.

I'm trying to put a C-style array inside a C++ std::map for later use when setting a color.

const map<int, GLfloat[3]> colors = { // 
    {1, {0.20. 0.60. 0.40}},          //
    ...                               // This produces an error.
    {16, {0.5, 0.25, 0.75}}           //
};                                    //

...

int key = 3;
glColor3fv(colors.at(key));

This does not compile because:

Semantic Issue
Array initializer must be an initializer list

...but I did specify an initializer list, didn't I? Why doesn't this work?

Upvotes: 2

Views: 1121

Answers (4)

Vlad from Moscow
Vlad from Moscow

Reputation: 310950

The problem is that arrays have neither copy constructor nor copy assignment operator. Instead of a C array use standard C++ container std::array that has the copy constructor and the copy assignment operator.

For example

#include <iostream>
#include <array>
#include <map>

using namespace std;

int main() 
{
    const std::map<int, std::array<float,3>> colors = 
    {
        { 1, { 0.20, 0.60, 0.40 } },
        { 16, { 0.5, 0.25, 0.75 } }
    };  

    return 0;
}

For simplicity I used type float instead of GLfloat in the example .

Upvotes: 2

R Sahu
R Sahu

Reputation: 206567

The type GLfloat[3], as a value type, does not meet the following requirements of associative containers.

  1. It is not EmplaceConstructible.
  2. It is not CopyInsertable.
  3. It is not CopyAssignable.

More details can be found at http://en.cppreference.com/w/cpp/concept/AssociativeContainer.

You can create a helper class to help you along.

struct Color
{
   GLfloat c[3];
   GLfloat& operator[](int i) {return c[i];}
   GLfloat const& operator[](int i) const {return c[i];}
};

const std::map<int, Color> colors = {
    {1, {0.20, 0.60, 0.40}},
    {16, {0.5, 0.25, 0.75}}
};  

Upvotes: 5

Germ&#225;n Diago
Germ&#225;n Diago

Reputation: 7663

It is not gonna be faster maybe, do to cache misses.

Use a sorted std::vector or array<std::pair<const Key, Value> and use std::lower/upper_bound to look for the element you want to look for. That will be faster, I guess.

Upvotes: -3

Ed Heal
Ed Heal

Reputation: 59997

Do this:

using std;
using namespace boost::assign;

map<int, GLfloat[3]> colors  = map_list_of (1, {0.20. 0.60. 0.40}) (16, {0.5, 0.25, 0.75});

Should do the trick.

Upvotes: 1

Related Questions