Squirrel

The programming language
Welcome to Squirrel Sign in | Join | Help
in Search

Overload support question

Last post 10-07-2007, 11:27 PM by Katsuaki Kawachi. 7 replies.
Sort Posts: Previous Next
  •  09-28-2007, 6:25 PM 2160

    Overload support question

    When I saw that overload support got added, I was really excited I could finally drop all my custom handlers for operator overloading on the OGRE math classes. Alas, it doesn't seem to be working out that way, and I am hoping there is a remedy to the issue. Basically, I am defining the overloadFunc as such:

    overloadFunc<Vector3 (Vector3::*)(const Vector3&)>(&Vector3::operator+, _T("_add"));

    The function as defined in the OGRE API is:

    Vector3 operator +(const Vector3& rkVector) const

    The error I am getting is:
    Error    2    error C2664: 'SqPlus::SQClassDefBase<TClassType> &SqPlus::SQClassDefBase<TClassType>::overloadFunc<Ogre::Vector3(__thiscall Ogre::Vector3::* )(const Ogre::Vector3 &)>(Mfunc,const SQChar *)' : cannot convert parameter 1 from 'overloaded-function' to 'Ogre::Vector3 (__thiscall Ogre::Vector3::* )(const Ogre::Vector3 &)'    d:\code\stasis\stasis.squirrel\src\vector3proxy.cpp    11   

    I am not sure if what I am trying to do is just not possible, perhaps because operator overloads aren't treated as normal functions, or if perhaps it's because of the const'ness of the method? In any case, is there a way to make this work? It would save me a ton of trouble by not having to maintain clumsy manual wrappers to make operators work for those classes.

    For some background, I can't use the regular func() because Vector3 has a unary and binary + operator, and when using regular func, it's an ambiguous symbol.
  •  09-28-2007, 9:50 PM 2161 in reply to 2160

    Re: Overload support question

    I think it's the const, because I have the same issue trying to wrap any overloaded function that is const. If I try and add const to the end of the function pointer definition, like so:

    Vector3 (Vector3::*)(const Vector3&) const

    Which is a valid function pointer type, SqPlus complains with the follow errors:

    Error    1    error C2027: use of undefined type 'SqPlus::Arg<Func>'    d:\code\squirrel2_1_1_sqplus_snapshot_20070927\sqplus\sqplusoverload.h    164   
    Error    2    error C2228: left of '.push_back' must have class/struct/union    d:\code\squirrel2_1_1_sqplus_snapshot_20070927\sqplus\sqplusoverload.h    164   
    Error    3    error C3861: 'num': identifier not found    d:\code\squirrel2_1_1_sqplus_snapshot_20070927\sqplus\sqplusoverload.h    164   

  •  09-28-2007, 9:54 PM 2162 in reply to 2161

    Re: Overload support question

    Fixed it! Needed to add Arg classes as such:

    template<typename T, typename R, typename A1>
    struct Arg<R(T::*)(A1) const> {
        static inline int num(void) {return 1;}
        static inline int argTypeDistance(HSQUIRRELVM v) {
            return Arg<R(*)(A1)>::argTypeDistance(v);
        }
    };

    Notice the const after the template type. Need one of those for each of the other Arg member function specializations, one for non-const (like you have) and one for const. I've added them to my local version.


    Edit: To save you some work, here is the updated sqplusoverload.h. I added a section below the non-const member function Arg specilizations wrapped in #ifdef SQPLUS_CONST_OPT that adds all the equivalent const member function Arg specializations.

    http://www.gnometank.net/sqplusoverload.h
  •  09-28-2007, 11:48 PM 2163 in reply to 2162

    Re: Overload support question

    Well, it seems I had to go a step farther. Operators can't be overloaded by ambiguity on type alone, the function dispatcher types must be a function of both the operator member function type and the name of the operator we are overloading. For instance, we can't just have MemberDispatcher<Vector3 (Vector3::*)(const Vector3&) const>, because if you registered _sub and _add to that, it would call the last function registered. So I had to extend the way overoading works to treat operators special.

    There is a new function, overloadOperator<typename Ofunc, const SQChar* Oname>(Ofunc func); It's used as such:

    overloadOperator<Vector3 (Vector3::*)(const Vector3&) const, OperatorAddName>(&Vector3::operator +);

    OperatorAddName has to be an external linkage character constant somewhere. I have it defined as:
    extern const char OperatorAddName[] = "_add".

    This is an unnecessary evil because of C++ templates needing external linkage for non-type parameters.

    I've tested it, and it works. It also works with operators that are actually overloaded, such as the * operator taking a Vector3 or a float. It's probably a bit kludgy, but it allows me to overload operators that would otherwise be ambiguous without having to write length wrapper functions, so I am happy. I can post the modified header if you want to see it. You may have a better way of accomplishing this, a C++ master I am not.
  •  09-29-2007, 8:43 AM 2164 in reply to 2162

    Re: Overload support question

    Hi,

    Thank you for your contribution!  I've merged your code for const member functions
    into branch at  https://sqplus.svn.sourceforge.net/svnroot/sqplus/branches/tegan-r119-overloadconst

    I'm now trying to understand what's going on in operator overloading.

    Regards,
    K. Kawachi
  •  09-30-2007, 9:40 AM 2165 in reply to 2164

    Re: Overload support question

    Let me get the code cleaned up and my thoughts about it sort of organized in my head and I will post the code, so you can see what I changed, and then try and explain why I think it works and had to be changed. It definitley WAS NOT working with overloadFunction, because of the way you match functions by signature. I also expanded all of SqPlus to allow functions/methods with up to 16 arguments, because I actually have a constructor in my project that takes 16 floats (4x4 matrix). I will post that as well.
  •  10-01-2007, 5:07 AM 2166 in reply to 2165

    Re: Overload support question

    OK, you're right.
    I find where is wrong in my implementation.  Thank you for pointing it out.
    I beleive I can fix it by adjusting SQOverloader::switcher without introducing external linkage.
    It will be done in this weekend.  Of course your contribution is welcome.

    Because I'm using this facility with a few overloaded functions, I couldn't notice
    my implemtation has defects unless you test it in your application.
    Thanks again.

    K. Kawachi
  •  10-07-2007, 11:27 PM 2177 in reply to 2165

    Re: Overload support question

    Hi,

    I've got it working.
    I introduced a new method "overloadOperator" which is slightly different
    from your suggestion.  Please check testSqPlus2unit/test_FunctionOverloading.cpp on SVN
     https://sqplus.svn.sourceforge.net/svnroot/sqplus/branches/tegan-r119-overloadconst

    It is a draft version, so there are some redundancy in SqPlusOverload.h. 
    If it works well with your project,  I will clean up and merge it into trunk.

    Regards,
    K. Kawachi
View as RSS news feed in XML
Powered by Community Server, by Telligent Systems