[C++-sig] implicit converter from enum to int problem

David Abrahams dave at boost-consulting.com
Tue Aug 20 18:42:12 CEST 2002


From: "gideon may" <gideon at computer.org>


> Dear Dave,
>
> I've been running into the same problem which Achim had regarding
> the use of enumeration types (see
> http://mail.python.org/pipermail/c++-sig/2002-May/001077.html). He wasn't
> able to compile the code which you posted.
> I tried something along the same line, which gave the following compiler
> error (osg::Material::Face is an enum):

Please in future post the code you're trying to compile along with the
compiler error. I think I understand what's happening in this case, though.

> C:\cvs_rep\boost\boost\boost\python\converter\implicit.hpp(43) : error
> C2440: '=' : cannot convert from 'int' to 'osg::Material:
> :Face'
>         Conversion to enumeration type requires an explicit cast
> (static_cast, C-style cast or function-style cast)
>         C:\cvs_rep\boost\boost\boost\python\converter\implicit.hpp(28) :
> while compiling class-template member function 'void bo
> ost::python::converter::implicit<Source,Target>::construct(PyObject
> *,boost::python::converter::rvalue_from_python_stage1_data *
> )'
>         with
>         [
>             Source=int,
>             Target=osg::Material::Face
>         ]
>
> In the mail from may you mentioned that you forgot the rule for
converting
> ints to enums. Has this been
> implemented ?

Uh, no.

> I changed python/converter/implicit.h @ line 43 to the following :
>         // new (storage)
> Target(*static_cast<Source*>(intermediate_data.stage1.convertible));
>         new (storage)
>
Target((Target)*static_cast<Source*>(intermediate_data.stage1.convertible))
;
>
> and now I'm able to compile and run my code. Is it right what I did ? It
> seems to work for me.

Well, that's a bit dicey since the C-style cast can work unintentionally in
so many situations, though I'm not really sure it's any worse than the
alternatives.

The real problem here is that your fix places additional requirements on
Target, namely that it's copy-constructible.

I'm truly not sure what to do about this one; it appears that the rules are
complicated. For example, just because you can write:

    enum Foo { foo = 42; }
    int y = 3;
    Foo x1 = Foo(y);

doesn't mean you can write:

    Foo* x2 = new Foo(y);

I've always found that the rules for fundamental types are abominably
confusing. Hell, I'm not even sure what the right formal name for these
things (which includes the scalars and enums) is. I'm going to try to get
some expert feedback about this. It's possible that the only good fix for
implicit.hpp is to do something which detects that the target type is one
of the builtins (or enum) that's known to be copy-constructible and
dispatches to a different implementation.

I'll let you know what I find out.

-Dave





More information about the Cplusplus-sig mailing list