1

I am trying to understand how to initialize private const std::map properly. I have studied this well-known topic but none of the answers was suitable for me, because I am forced to use old gcc and boost versions (gcc 4.4, boost 1.41 -> C++11 features are limited, boost::asign::map_list_of does not compile) and, moreover, I don't want to use class member function for std::map initialization due to need of doing that outside the class at the time of the object construction.

However, there is overloaded constructor for std::map that accepts two iterators (this thread inspired me too), and this is my workaround:

template <typename Arg, typename Callback>
class CallbackSelector
{
    private:
        const std::map<Arg, Callback> Mapping;

    public:
        CallbackSelector(std::pair<Arg, Callback> _Mapping[]):
            Mapping(_Mapping, _Mapping + sizeof(_Mapping)/sizeof(std::pair<Arg, Callback>))
            {
                //BOOST_ASSERT(sizeof _Mapping)/(sizeof (std::pair<Arg, Callback>)) == 2);
                std::cout << "sizeof _Mapping " << sizeof _Mapping << std::endl;
                std::cout << "sizeof (std::pair<Arg, Callback>) " << sizeof (std::pair<std::string, boost::function<void(void)> >) << std::endl;
            };
};

void PamEvent() {}

void DefaultEvent() {}

int main(int argc, char** argv)
{
    std::pair<std::string, boost::function<void(void)> > _Mapping[] =
    {
        std::make_pair("pam:", boost::bind(&PamEvent)),
        std::make_pair("none", boost::bind(&DefaultEvent))
    };
    std::cout << "sizeof _Mapping " << sizeof _Mapping << std::endl;
    std::cout << "sizeof (std::pair<Arg, Callback>) " << sizeof (std::pair<std::string, boost::function<void(void)> >) << std::endl;

    CallbackSelector<std::string, boost::function<void(void)> > Selector(_Mapping);
}

(The full executable version of this example)

If I uncomment the line with BOOST_ASSERT macro, this code will not be compiled, because the size of Mapping is unequal to 2 due to an error of passing the std::pair<std::string, boost::function<void(void)> > _Mapping[] into the CallbackSelector class constructor. You can verify this by looking at the output:

sizeof _Mapping 80                                 //in the int main()
sizeof (std::pair<Arg, Callback>) 40

sizeof _Mapping 8                                  //in the CallbackSelector constructor
sizeof (std::pair<Arg, Callback>) 40               //the array size has decreased tenfold

I'll be glad if someone could find this (apparently?) simple mistake. Thank you.

1
  • 1
    Concerning the sizes, _Mapping[] as a function parameter is just a pointer. Commented Mar 24, 2014 at 13:08

1 Answer 1

2

There's no way to determine the size of an array given just a pointer to it. You could either pass the size as a separate argument:

CallbackSelector(std::pair<Arg, Callback> mapping[], size_t size) :
    Mapping(mapping, mapping + size)

or infer it as a template parameter:

template <size_t size>
CallbackSelector(std::pair<Arg, Callback> (&mapping)[size]) :
    Mapping(mapping, mapping + size)

or, in C++11 or later, you could take an initializer_list argument

CallbackSelector(std::initializer_list<std::pair<Arg, Callback>> mapping) :
    Mapping(mapping.begin(), mapping.end())

// Usage example
CallbackSelector<std::string, boost::function<void(void)> > selector {
    {arg1, callback1}, 
    {arg2, callback2}
};

(Note: I took the liberty of renaming _Mapping, a reserved name that you shouldn't have been using).

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for an amazing answer. The last option worked even with my old gcc 4.4.7. If you don't mind I'll add the template definition to your code examples.
I've used the template trick in the past for passing array sizes. Works like a champ.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.