Closed notlion closed 10 years ago
Unfortunately, the way you have to do it is by static_cast-ing the function signature you want on this to work properly:
static_cast<void (vector::*) ( float, float )>( &vector::set );
Replace (float, float) with the arguments to you, and void
with the return type, etc. etc.
Note that in the bowels of sol
, we do some overload in-fighting to figure out the proper thing with the set_function
syntax. It might be worth elevating this to a regular free-function that users can use to avoid this problem entirely.
Thanks! The static cast works well enough. It would be nice to have something akin to set_function<void(float, float)>()
for userdata. Related question: Is it possible to modify userdata after it is created?
I don't think allowing modification of userdata<T>
after it's been made to be a wise design decision, plus it actually will make a few things much harder about automatic cleanup (we can get away with using non-garbage free functions for cleanup of userdata metatables because we are using variadic templates to guarantee a fixed, compile-time count of the number of functions associated with a userdata type).
That being said, an "easy" overload resolution "resolve" function would be helpful, and would also help us identify an error with some clang overload resolution problems.
Resolve would be nice. Basically something like this?
sol::userdata<Vec2f> udata("Vec2", ctor, "set", sol::resolve<float, float>(&Vec2f::set));
This was my use case but for some reason I was thinking about it in terms of modifying userdata after creation. This seems simpler.
So I have a version of that working... in g++. Clang barfs because of the return type, so I need to add an extra level of indirection to make clang behave.
Just checked in something for this (resolve.hpp
). Note how if you're using clang (or plan to build with clang), clang does not nicely handle specifying the arguments only, so you MUST specify the full signature if you want to build with clang.
With g++, you can use the argument-only form and everything should be peachy-keen. g++:
sol::userdata<Vec2f> udata("Vec2", ctor, "set", sol::resolve<float, float>(&Vec2f::set));
clang:
sol::userdata<Vec2f> udata("Vec2", ctor, "set", sol::resolve<void(float, float)>(&Vec2f::set));
The clang version will work everywhere.
Awesome. Yup, I'm stuck with clang because I'm targeting iOS / using Xcode.
Interestingly, when the return type is void
, these work (where T is double
):
sol::resolve<T, T>(&VecT::set) // void(T, T)
sol::resolve<const Vec2<T>&>(&MatrixT::scale) // void(const Vec2<T>&)
But this does not:
sol::resolve<T>(&MatrixT::rotate) // void(T)
Thanks for the improvement. Sol is really nice so far!
Yeah, clang is weird... I think it actually might be a defect in clang
, the more I think about it. I will have to ask.
But glad it's all good. If you run into any more peculiarities or things, feel free to drop more bug reports. If you have any interesting library ideas, feel free to drop feature requests too!
As it stands, it seems Clang's actually completely correct in not being able to resolve things. It's more "conformant" behavior (according to 14.8.1 [temp.arg.explicit]/9 pointed out by Stephan T. Lavavej), so... yeah. I guess g++ isn't conforming. Use the signature version ( R( Args... )
) to be as explicit as possible, or static_cast
.
This has been fixed.
Is there a way to select which version of a overloaded function to use when creating userdata? This is a class similar to the one I'm trying to bind:
So given that there are two versions of
set
, how do I choose which one to bind?