views:

260

answers:

1

I created a class CMyClass whose CTor takes a UCHAR as argument. That argument can have the values of various enums (all guaranteed to fit into a UCHAR). I need to convert these values to UCHAR because of a library function demanding its parameter as that type.

I have to create a lot of those message objects and to save typing effort I use boost::assign:

std::vector<CMyClass> myObjects;
        boost::assign::push_back(myObjects)
            (MemberOfSomeEnum)
            (MemberOfSomeEnum);

std::vector<CMyClass> myOtherObjects;
        boost::assign::push_back(myObjects)
            (MemberOfAnotherEnum)
            (MemberOfAnotherEnum);

The above code calls the CMessage CTor with each of the two enum members and then puts them in a list. My problem is, that this code throws the warning C4244 (possible loss of data during conversion from enum to UCHAR) on VC++9.

My current solution is to create a conversion function for each enum type:

static UCHAR ToUchar(const SomeEnum eType)
{
    return static_cast<UCHAR>(eType);
}

static UCHAR ToUchar(const AnotherEnum eType)
{
    return static_cast<UCHAR>(eType);
}

And then the above code looks like this:

std::vector<CMyClass> myObjects;
        boost::assign::push_back(myObjects)
            (ToUchar(MemberOfSomeEnum))
            (ToUchar(MemberOfSomeEnum));

std::vector<CMyClass> myOtherObjects;
        boost::assign::push_back(myObjects)
            (ToUchar(MemberOfAnotherEnum))
            (ToUchar(MemberOfAnotherEnum));

This is the cleanest approach I could think of so far.

Are there any better ways?
Maybe boost has something nice to offer?

I don't want to disable warnings with pragma statements and I cannot modify the enums.

+5  A: 

I wouldn't be emabarrassed by static_cast here, but if you are:

template <class T>
inline UCHAR ToUchar(T t)
{
    return static_cast<UCHAR>(t);
}

saves writing a function for every enum.

fizzer
That would result in having to write "ToUchar<SomEnum>(SomeEnumMember)" each time which would be less readable. That's what I meant with "clean".
mxp
No, the template argument is deduced: ToUchar(SomeEnumMember)
fizzer
Sorry, you're right! I should have tried it before writing the comment... :-/
mxp
The only downside to this neat solution is that it allows erroneous enums to be converted to UCHAR without compiler warnings. The explicit constructors ensure that only the enums that intended for use will be used without warning.
Jonathan Leffler