3

I have a class that stores a function pointer to some binary function

class ExampleClass
{
private:
    double(*_binaryFunction)(double, double);
}

How can I return this pointer in a const "getter"? This is either surprisingly hard to search for or nobody else has asked this. If the function weren't const, the syntax would be

double (*GetBinaryFunction())(double, double);

Where do I put the const qualifier? Like this?

double (*GetBinaryFunction() const)(double, double);

If I wanted to use a typedef, the syntax would be: (right?)

typedef double (*BinaryFunction)(double, double);
BinaryFunction GetBinaryFunction() const;

Not answering this question but still useful: C syntax for functions returning function pointers (does not deal with const member functions)

Also I want to re-iterate that I don't want to return or am dealing with any pointer-to-member.

To address duplicates:
The more precise formulation of this question would be "Where to syntactically put the cv-qualifier in the declaration of a member function returning a function pointer?" The answer turned out to be surprising (in the middle of the declaration, not at the end as is usually the case) and none of the linked questions deal with the question of the const keyword position, only with broader syntax of function returning function pointer.

Jan Hošek
  • 187
  • 1
  • 9
  • *Why* don't you want to make a type-alias, if it will make things so much easier? – Some programmer dude Aug 31 '22 at 10:49
  • As for your problem of where to place the `const`, you basically have only two alternatives. Why not simply try both of them and see what compiles? – Some programmer dude Aug 31 '22 at 10:51
  • 1
    @Someprogrammerdude In the end I did use it, but A: I was curious about this abomination and B: didn't want to leak the typedef out of the class, to introduce dependence somewhere. And yes, I could (did) experiment and guessed it correctly but again, nobody else seems to have asked this before. – Jan Hošek Aug 31 '22 at 10:51
  • "the syntax would be" -- no, it wouldn't be. Try it. It won't work. `_binaryFunction` is not a function. It is a non-static class method. Non-static class methods cannot be converted to function pointers. Try every which way to convert it to a `double (*)(double, double)` -- it won't work. The question is based on a flawed premise. – Sam Varshavchik Aug 31 '22 at 10:54
  • @JanHošek what do you mean by "to leak the typedef" ? Isn't making it e.g. private good enough if you want to use it only for the implementation ? – wohlstad Aug 31 '22 at 10:54
  • 1
    @KamilCuk Yes, but i am asking about the syntax declaring the getter function. Of course the body is just `return _binaryFunction;` – Jan Hošek Aug 31 '22 at 10:58
  • @wohlstad I suppose that is another question, I wasn't very familiar with private typedefs in declarations of public functions but don't worry about that. – Jan Hošek Aug 31 '22 at 11:00
  • even when public, it doesn't "leak". It would be `ExampleClass::function_type` which cannot be confused with any other `function_type` – 463035818_is_not_an_ai Aug 31 '22 at 11:03
  • @463035818_is_not_a_number Yes of course but then somebody (lazy me) uses `ExampleClass::function_type` somewhere else where they could have used the "simple" function pointer and suddenly that place has dependence on example_class.h when it doesn't have to XD – Jan Hošek Aug 31 '22 at 11:05
  • if they need the type of the function pointer in `ExampleClass` and they are using `ExampleClass::function_type` then the type can change and the code using the alias is still using the right type. – 463035818_is_not_an_ai Aug 31 '22 at 11:12

3 Answers3

2

How can I return this pointer in a const "getter"?

Examples:

struct ExampleClass
{
    double (*_binaryFunction)(double, double);
    double (*GetBinaryFunction() const)(double, double) {
        return _binaryFunction;
    }

    typedef double (*BinaryFunctionTypedef)(double, double);
    BinaryFunctionTypedef GetBinaryFunction2() const {
        return _binaryFunction;
    }

    using binaryFunctionUsing = double (*)(double, double);
    binaryFunctionUsing GetBinaryFunction3() const {
        return _binaryFunction;
    }
};
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
2

To add upon what has been said, I think it's also important to mention the correct syntax for references.


  • for the normal reference:
double (*&GetBinaryFunction())(double, double)

  • and for the const& version:
double (*const& GetBinaryFunction() const)(double, double)

the first const describes the return type (a function pointer that is a const reference) and the second const describes the ExampleClass member constness.


example:

#include <iostream>
#include <cmath> //for std::pow

class ExampleClass {
public:
    double (*&GetBinaryFunction())(double, double) {
        return this->_binaryFunction;
    }
    double (*const& GetBinaryFunction() const)(double, double) {
        return this->_binaryFunction;
    }

private:
    double(*_binaryFunction)(double, double);
};

void foo(ExampleClass& example, double a, double b) {

    example.GetBinaryFunction() = std::pow;

    std::cout << "foo( & ) : " << example.GetBinaryFunction()(a, b) << '\n';
}

void bar(const ExampleClass& example, double a, double b) {
    std::cout << "bar( const& ) : " << example.GetBinaryFunction()(a, b) << '\n';
}

int main() {
    ExampleClass example;
    foo(example, 2, 5);
    bar(example, 2, 6);
}

output:

foo( & ) : 32
bar( const& ) : 64

if you don't like the long syntax and don't want to use typedef or using you can also simply use auto:

auto& GetBinaryFunction() {
    return this->_binaryFunction;
}
const auto& GetBinaryFunction() const {
    return this->_binaryFunction;
}

it will compile into the same code as above. to not use reference, simple remove the & from the auto.

Stack Danny
  • 7,754
  • 2
  • 26
  • 55
1

You can use an auto return type

class ExampleClass
{
    auto get() const { return _binaryFunction; }
private:
    double(*_binaryFunction)(double, double);
};
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185