Colobot Forum - International Colobot Community

Full Version: Smarter overloading method?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I made this. 3 simple functions with overloads to cover all possible parameter combinations. The problem is that code lenght scales expotentially with number of parameters. Is there smarter/shorter way to make function with parameters that can be different types?
Code:
extern void object::Libr(){}

public object object::pick(point p) {
    goto(p);
    grab();
    return load;
}

public object object::pick(object o) {
    return pick(o.position);
}

public object object::pick(int cat) {
    return pick(radar(cat));
}

public void put(point p){
    goto(p);
    drop();
}

public void put(object o){
    put(o.position);
}

public void put(int cat){
    put(radar(cat));
}

public void transport(point what, point where){
    pick(what);
    put(where);
}

public void transport(point what, object where){
    transport(what, where.position);
}

public void transport(point what, int where){
    transport(what, radar(where));
}

public void transport(object what, point where){
    transport(what.position, where);
}

public void transport(object what, object where){
    transport(what.position, where.position);
}

public void transport(object what, int where){
    transport(what.position, radar(where));
}

public void transport(int what, point where){
    transport(radar(what), where);
}

public void transport(int what, object where){
    transport(radar(what), where.position);
}

public void transport(int what, int where){
    transport(radar(what), radar(where));
}
You can encapsulate your arguments into classes using multiple constructors. It's still fairly ugly, but rather than scaling exponentially on the number of arguments the complexity scales linearly on the number of types of argument.

Here's a trivial example using two arguments of the same type (a location specified as an object, a point or a category):

Code:
public class Thing {
    void Thing( point np ) {
        p = np;
    }
    void Thing( object thething ) {
        p = thething.position;
    }
    void Thing( int category ) {
        object thething = radar(category);
        p = thething.position;
    }
    
    point p;
}

float distanceofthings( Thing a, Thing b ) {
    return distance( a.p, b.p );
}

extern void object::Main()
{
    object item = radar(Me);
    point p = item.position;
    
    float d = distanceofthings( new Thing(this), new Thing(p) );
    message( "Distance to player avatar " + d );
    
    d = distanceofthings( new Thing(this.position), new Thing( SpaceShip ));
    message( "Distance to spaceship " + d );
}

You can see that the overloaded Thing() constructors effectively convert each argument to a Point as the time that the function is called, so I don't have to overload the function at all. If I wanted to add a fourth acceptable argument type, I'd just add another Thing constructor.