[C++-sig] Re: long long unsigned issue...
Milind Patil
milind_patil at hotmail.com
Sun May 4 00:35:50 CEST 2003
"David Abrahams" <dave at boost-consulting.com> wrote in message
news:uk7d8n8k7.fsf at boost-consulting.com...
> "Milind Patil" <milind_patil at hotmail.com> writes:
>
> > Hi,
...<snipped>...
> > Why wouldn't it try yo convert to long long unsigned int before trying
> > out int?
>
> Because of the order of your implicitly_convertible<...> invocations.
> Conversions to a C++ type (Y in this case) get tried in the order
> they're registered. I know; it's confusing since that's the opposite
> of the way overloads work.
>
This clears some of my puzzlement. Thank you.
> Are you sure you want the implicitly_convertible invocations? You
> don't need them in order to be able to compile and run the code above.
> The only reason you would need them was if you wanted to be able to
> pass a Python int or long directly to a wrapped C++ function accepting
> a Y or Y const& argument.
...<snipped>...
> That's because the constructor overloads get searched first (in
> reverse order), then converters to the argument types get searched (in
> forward order).
>
> In your original example it was finding Y(const Y&) and looking for a
> converter to the Y argument, finding the implicit converter for Python
> Int -> Y, which is a good enough match to use with long values.
>
> There's a lot of redundancy in all your declared constructors and
> especially in the use of implicitly_convertible. You might consider
> starting with a minimal set of functionality (using unsigned long long
> only) and seeing if you can get that to do what you want.
>
You are right of course about this particular example not needing the
implicity_convertibles.
But, taking the toy example a step closer to the actual class I am
wrapping...
class Y {
public:
Y() : y(0L) { }
Y(int y) : y(y) { }
Y(long long unsigned int y) : y(y) { }
Y(int s, const Y & y) : y(y << s/* toy usage*/) { }
Y(Y const& rhs) : y(rhs.y) { }
virtual ~Y() { }
operator int() const { return y; }
void operator=(Y const& y) {
this->y = y.y;
}
long long unsigned int y;
};
BOOST_PYTHON_MODULE(hello)
{
class_< Y >("Y", init< >())
.def(init< const Y & >())
.def(init< int, const Y & >())
.def(init< int >())
.def(init< long long unsigned int >())
.def_readwrite("y", &Y::y)
.def("__int__", &Y::operator int)
;
}
This should work, ... intutively. But doesn't, if I tried
to execute the python code...
z = hello.Y(2, 1)
Why should I now need
implicitly_convertible<int, Y>();
for it to work?
> > I am seeking a behaviour where python int is converted to c++ int
> > before constructing to c++ object Y, and python long is converted
> > to c++ long long unsigned int before constructing to c++ object Y.
>
> That might be difficult. Guido and the lads are making it
> increasingly difficult to detect a difference between Python int and
> Python long, and plan to erase the distinction altogether soon.
>
> Do you really need to handle the cases differently?
>
Not explicitly. But consider if I want to do
z = hello.Y(~0)
or
z = hello.Y(-1)
This is best converted to Y(int) constructor. But python still insists
on calling the Y(long long unsigned int) constructor and craps out saying
about bad argument type.
> --
> Dave Abrahams
> Boost Consulting
> www.boost-consulting.com
Part of the c++ library I am wrapping is a bit vector library which
acts like a c++ builtin type for most part. It is only when converting
python types to the bit vector object that differences become
visibile according to whether source type is signed or not.
I read up a bit on python long and learned that it is not like the
c++ long. It seems the python long is a structure and is not
width bound. How does boost handle python boost to long
conversion?
Thank you for the quick response.
Milind
More information about the Cplusplus-sig
mailing list