Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Meaning of constant function pointer

I was reading through someone else’s code that had custom function classes similar to boost::function or std::function. They were passing these function classes around by constant reference. In one section on the critical path they chose to use function pointers instead but still by constant reference with comments about greater efficiency

They had the equivalent of this in their code:

using FuncT = int(*)(int, int);

Which was being passed around like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const FuncT&

I assume const FuncT& isn’t really any more efficient to pass than FuncT and that the syntax was just leftover of it being their custom function class originally. However it got me wondering about what the meaning of const FuncT would be

#include <iostream>

using FuncT = int(*)(int, int);

struct MyClass final {
    static int myMethod(int a_arg1, int a_arg2) {
        std::cout << a_arg1 << " " << a_arg2 << std::endl;
        return 0;
    }

    // Similar to what I found in someone's code
    void v1(const FuncT& a_func) { a_func(1, 1); }

    // A reference to a const function pointer seems meaningless, it should be
    // just as efficient to copy the pointer
    void v2(const FuncT  a_func) { a_func(2, 2); }
    //                 ^
    //                 Removed reference

    // I believe this is the syntax for a function pointer that cannot be
    // modified to point to a different function
    void v3(      int(* const a_func)(int, int)) { a_func(3, 3); }
    //                  ^
    //                  Added const not present in FuncT

    // This compiles but I don't know what the intended meaning of the extra
    // const would be
    void v4(const int(* const a_func)(int, int)) { a_func(4, 4); }
    //      ^
    //      Added const not present in v3
};

int main() {
    MyClass myClass;
    myClass.v1(&MyClass::myMethod);
    myClass.v2(&MyClass::myMethod);
    myClass.v3(&MyClass::myMethod);
    //myClass.v4(&MyClass::myMethod); // Doesn't compile
    return 0;
}

In the above code v4 compiles but what is the intended meaning of the leftmost const?

>Solution :

Minor modifications to your code:

void v3( int(* const a_func)(int, int)) { 
    a_func = &MyClass::myMethod; // no, a_func is const
} 

a_func is const you cannot modify it. Trying to assign to it raises an error.

Here:

void v4(const int(* const a_func)(int, int)) { a_func(4, 4); }
//      |-------|
        

same as above, but the return type of the function is const int rather than int:

const int foo(int,int) { return 42;}

int main() {
    MyClass myClass;
    myClass.v4(&foo);
}

Live Demo

Something that still confuses me is why const FuncT is not equivalent to v4‘s argument

Grammar for function pointers is weird, thats why we use aliases as often as possible. For a thorough explanation I refer you to the respective literature. In this case it is just returntype (* outer_most_const)(parameter_types), while with the alias using f = returntype (*)(parameter_types) you add the outermost const via const f.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading