I have the following code:
enum class MessageDeliveryMethod
{
POST_MASTER,
BUBBLE,
NUM_ENUMERATORS
};
namespace
{
using MapType = std::array<
std::pair<char const*, MessageDeliveryMethod>,
static_cast<std::size_t>(MessageDeliveryMethod::NUM_ENUMERATORS)
>;
MapType g_mapping = {{
{"POST_MASTER", MessageDeliveryMethod::POST_MASTER},
{"BUBBLE", MessageDeliveryMethod::BUBBLE},
}};
}
This compiles but I don't know why. The g_mapping
variable requires an extra level of seemingly redundant curly braces. In other words, I expect the initialization to look like:
MapType g_mapping = {
{"POST_MASTER", MessageDeliveryMethod::POST_MASTER},
{"BUBBLE", MessageDeliveryMethod::BUBBLE},
};
(One level of outer braces removed).
My understanding is that prior to C++14, when doing direct initialization the extra level of braces is required. However, copy initialization was not supposed to require this based on this page (look at the example there).
Can anyone explain this?
This SO question which is presumed to be duplicated by my question does indeed answer some specific and helpful questions (related to my own) however out of context mine was confusing due to the usage of pair
(which I thought was causing the issue initially). I never would have found that SO question in the first place, so if anything I think perhaps the way I've worded my question may help people arrive to the solution from different angles.
std::array
is defined as a structure that contains an array.
Thus the first pair of braces are used to initialize data members of the structure that is the array. The second pair of braces is used to initialize the array within the structure. And the third pairs of braces are used to initialize each object of type std::pair.
To be more precise then according to the C++ Standard (23.3.2.1 Class template array overview)
2 An array is an aggregate (8.5.1) that can be initialized with the syntax
array<T, N> a = { initializer-list };
where initializer-list is a comma-separated list of up to N elements whose types are convertible to T.
std::array
is defined to be a nested aggregate - a class containing an array as its only member. Prior to C++14, aggregate initialisation needed two levels of braces: one to surround the class member list (in which there was only one member, the array), and one to surround the array element list. Then you need a third level if, as here, you want to list-initialise each array element.
C++14 allows you to "flatten" the lists when initialising nested aggregates, as described in the page you link to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With