Nicolás Videla
Nicolás Videla

Reputation: 44

C/C++ function as parameter

bool isContainedSameForm(AG ag1, AG ag2){
    if(isEmpty(ag2)) return false; 
    return isContainedSameForm(ag1->pH,ag2->pH) && isContainedSameForm(ag1->sH,ag2->sH);
};
int sameFormOcurrences(AG ag1,AG ag2,bool (*isContainedSameForm)(AG,AG)){
    if(isEmpty(ag2)) return 0;
    int ret=0;
    if(isContainedSameForm(ag1,ag2)) ret=1;
    return ret + sameFormOcurrences(ag1,ag2->pH,isContainedSameForm) + sameFormOcurrences(ag1,ag2->sH,isContainedSameForm);
};

int sameFormOcurrences( AG ag1, AG ag2){
    return sameFormOcurrences(ag1,ag2,isContainedSameForm);
}

AG being a general tree, this counts how many times a tree of the same form appears in the second tree

enter image description here

What I don't understand is the purpose of the first sameFormOcurrences function receiving a isContainedSameForm in parameters.

Is is just a way to change the signature without changing the name of it? Isn't it redundant with the function being declared above already if it's trying to avoid a non defined method?

Upvotes: 0

Views: 85

Answers (1)

Ben Voigt
Ben Voigt

Reputation: 283634

This code isn't written in the best style, the function pointer parameter, and the function implementing that, really should have different names. Right now if there were a typo in the parameter declaration, the code inside the function would refer directly to another function, and the parameter would silently become useless.

This would be much better:

int countMatchingDescendants(AG ag1,AG ag2,bool (*matchCondition)(AG,AG))
{
    if(isEmpty(ag2)) return 0;
    int ret=0;
    if(matchCondition(ag1,ag2)) ret=1;
    return ret + countMatchingDescendants(ag1,ag2->pH,matchCondition) + countMatchingDescendants(ag1,ag2->sH,matchCondition);
}

bool isContainedSameForm(AG ag1, AG ag2)
{
    if(isEmpty(ag2)) return false; 
    return isContainedSameForm(ag1->pH,ag2->pH) && isContainedSameForm(ag1->sH,ag2->sH);
}

int sameFormOcurrences( AG ag1, AG ag2)
{
    return countMatchingDescendants(ag1,ag2,isContainedSameForm);
}

Note that I've only changed identifier names, not the structure of the code (I also removed extraneous semicolons outside the function bodies). But now the counting code has a generic name indicating how flexible it actually is.

By changing the order, I prevent any possibility of the generic counting code accidentally referring to a concrete implementation.

Upvotes: 2

Related Questions