1

Is it possible to invoke the function of a class based on the fact that it is the only public one ? What I mean:

Something like:

double res = MyClass().myFunction(n);

becomes

double res = MyClass()[0](n);

Ideally I would have liked to call the function using a string with its name:

double res = MyClass().reflection("myFunction")(n);

But it seems not possible without wasting at least twice the ink to write the function name (function pointer and corresponding string in a map).

2
  • @AntoninGAVREL Depends on what you actually need, but you also can easily realize such call using a lambda function defined on the fly (capture of local variables is possible without need for extra parameters). Commented Feb 23, 2021 at 18:33
  • Why do you want this? Commented Feb 23, 2021 at 19:06

2 Answers 2

5

You can overload the call operator of the class. This is commonly called a Functor:

class MyClass {
public:
    int operator()(int param) const {
        return functionName(param);
    }

    int functionName(int param) const { return param; }
};

MyClass c;
int returnVal = c(3);

Edit addressing const comment:

The function and operator do not need to be const. You should mark functions const whenever the function does not modify the state of the object. This gives more information to people calling the function and is particularly important in multi-threaded applications. If the function you are calling is not const you can remove the const from the overload.

See this for more info.

Sign up to request clarification or add additional context in comments.

6 Comments

@AntoninGAVREL You can do anything you want in the body of the overloaded operator and you can replace int param with any arguments you want. It works just like a function. You can call other functions from there as well.
I trust you but I get error: passing ‘const MyClass’ as ‘this’ argument discards qualifiers [-fpermissive]
@AntoninGAVREL In your case, you'd need a call operator overload as shown here, which takies a parameter of type const std::string&, which is used then to translate to the actual function call (e.g. using a std::map<std::string,std::function<void()>. If you need additional (input / output) parameters add them as needed, but you must have a function / operator call signature, which fit's for all the functions you want to call that way. C++ deosn't really support reflection.
That means that the instance of the class you are calling the operator on is const and you did not mark the operator as const.
@DeanJohnson Consider expanding your example with another one following my comment. That will less confuse the OP, what they can do with the call operator overload (functor).
|
2

You can get something close to what you wrote by overloading the [] operator:

#include <iostream>
class MyClass
{
public:
  double operator [] (int n)
  {
    return functionName (n);
  }

private:
  double functionName (int n)
  {
    return n + 1;
  }
};


int main ()
{
  int n = 1;
  double res = MyClass ()[n];
  std::cout << "res: " << res << std::endl;
  return 0;
}

See the result here.

Notice tha here, the parameter passed to [] is shown to be of size_t, but I don't think that is a requirement by the standard. I was able to make it work for std::string as well.

#include <iostream>
#include <string>
class MyClass
{
public:
  std::string operator [] (std::string n)
  {
    return functionName (n);
  }

private:
  std::string functionName (std::string n)
  {
    return n + '1';
  }
};

int
main ()
{
  std::string n = "test";
  std::string res = MyClass ()[n];
  std::cout << "res: " << res << std::endl;

}

See here

4 Comments

very nice as well +1
The array subscript operator used here is often defined with size_t as the parameter, but that is just a convention because of what the operator is usually used for (indexing into containers). That is not required by the language standard.
@Ari "But interestingly, I was able to make it work even for std::string!" Yup! Proven since the very 1st version of std::map<KeyType,ValueType> once was instantiated with the type std::string as KeyType ;-) And the same for the call operator overload operator()(const std::string& fnName) BTW.
"the parameter passed to [] should be of size_t" there is no such requirement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.