Search code examples
c++c++11initializer-list

How to avoid error of narrowing conversion in c++11


I have the below code which uses enum value to initialize the vector of the struct. I was getting the error regarding narrow conversion. I have referred the Microsoft doc : link by which I can solve the issue by below code.

#include <iostream>
#include <vector>
#include <string>

enum NUMBERS
{
    NUMBERS_ZERO    = 0xA0000000,
    NUMBERS_ONE     = 0xA0000001,
    NUMBERS_TWO     = 0xA0000002,
    NUMBERS_THREE   = 0xA0000003,
};

struct Person {
    uint32_t        m_id = 0;
    std::string     m_name;

    Person(uint32_t id, std::string name) :
        m_id(id), m_name(name) {}
};

std::vector<Person> PersonList =
{
    {static_cast<uint32_t>(NUMBERS_ZERO),   "abc"},
    {static_cast<uint32_t>(NUMBERS_ONE),    "pqr"},
    {static_cast<uint32_t>(NUMBERS_TWO),    "xyz"},
    {static_cast<uint32_t>(NUMBERS_THREE),  "zzz"}
};

int main()
{
    for (auto it : PersonList)
        std::cout << it.m_id << " : " << it.m_name << "\n";
    return 0;
}

Since we can see the above initialization of vector with typecasting looks weird/complex. How can I improve the code with more readability. I have tried the below code, but it throws error: Conversion from 'Numbers' to 'uint32_t' requires a narrow conversion. Any suggestion would be appreciated.

/*
struct Person {
    uint32_t        m_id = 0;
    std::string     m_name;

    Person(uint32_t id, std::string name) :
        m_id(static_cast<uint32_t>(id)), m_name(name) {}
};

std::vector<Person> PersonList =
{
    {NUMBERS_ZERO,  "abc"},
    {NUMBERS_ONE,   "pqr"},
    {NUMBERS_TWO,   "xyz"},
    {NUMBERS_THREE, "zzz"}
};
*/

Solution

  • You can define a type to use for the enumeration which will make the casts not needed:

    enum NUMBERS : uint32_t
    {
        NUMBERS_ZERO    = 0xA0000000,
        NUMBERS_ONE     = 0xA0000001,
        NUMBERS_TWO     = 0xA0000002,
        NUMBERS_THREE   = 0xA0000003,
    };
    

    Without the type definition the numbers can be assumed to be signed and not fitting into a 32bit integer so narrowing conversion is used.