Call a class method inside a function which was passed as a string parameter

Viewed 89

EDIT: getPropertySingle and getPropertySingle are class methods of the most base class obj2_t in a hierarchy, different from the most base class obj_t for fAggregate.

This seemed irrelevant (I omitted it as a simplifiction, now added), and the issue posted here on obj_t::*fAggregate seems to be solved by the comment of The Dreams Wind. Now the code compiles. The method is

template<typename retval_t>
const retval_t obj2_t::getProperty(
        const obj_t& obj,
        const retval_t (*fProp)(const vec_t&, const string&, const int),
        const retval_t (obj_t::*fAggregate)(const retval_t&),
        const vec_t& vec,
        const string& s,
        const int i)
{
    const retval_t retval = getPropertySingle<retval_t>(fProp, vec, s, i);
    return obj.*fAggregate(retval);
};

But all target fProp are non-static members of obj2_t. Each specific fProp corresponds with a specific fAggregate, so when specifying on fProp (the reason for templating) there are no more template arguments. An example would be

const int obj2_t::getX(
        const obj_t& obj,
        const vec_t& vec,
        const string& s,
        const int i)
{
    const int retval = getProperty<int>(obj, obj2_t::getXSingle, obj.AggregateX, vec, s, i);
    return retval;
};

This brings compile error invalid use of non-static member function... But this is worth a separate consideration/question.


I have a templated function, obj2_t::getPropertySingle, which takes a function as an argument (I would later write explicit instantiations). In principle, the only reason for templating is simply applying various functions (fProp), each returning a different type retval_t, to the same set of arguments (vec, s, i). I will probably need later on to make it a variadic template.

template<typename retval_t>
const retval_t obj2_t::getPropertySingle(
        const retval_t (*fProp)(const vec_t&, const string&, const int),
        const vec_t& vec,
        const string& s,
        const int i)
{
    return fProp(vec, s, i);
};

Then I have another templated function, whose arguments are: 1) one object (obj) of any class in a hierarchy (obj_t being the most base), 2) one method (fAggregate), which should be present in any of those classes, 3) the same arguments in obj2_t::getPropertySingle so it can be applied.

template<typename retval_t>
const retval_t obj2_t::getProperty(
        const obj_t& obj,
        const retval_t (*fProp)(const vec_t&, const string&, const int),
            1) const string fAggregateStr,        OR
            2) const retval_t (*fAggregate)(const retval_t&),
        const vec_t& vec,
        const string& s,
        const int i)
{
    const retval_t retval = getPropertySingle<retval_t>(fProp, vec, s, i);
    return obj."fAggregateStr"(retval);    <---- HOW TO DO THIS?
};

I mean to pass fAggregate as a string (option 1 above). AFAIK, that is called reflection, and C++ doesn't support it.

Is there any alternative way of achieving this?
I don't know if something like option 2 can be used, because the method fAggregate itself is formed by joining obj and fAggregateStr. I could remove obj from the list of arguments, and pass directly fAggregate as obj."fAggregateStr" from the caller. But that would remove the possibility of combining any obj_t with any "fAggregateStr".

The workaround posted here is quite more complex in my case, if even feasible, like this.

Notes:

  1. I can conceive cases where in requirement 1 above obj_t is not necessarily any in a single hierarchy. In such case one would likely need to template also on that argument.
  2. The requirement 2 is automatically satisfied in my case, since it is a class member for the most base class obj_t. In the case of note 1 above, it wouldn't be automatic.
1 Answers

The issue on obj_t::*fAggregate seems to be solved by the comment of The Dreams Wind, which templates on obj_t also; not needed here.

Now the code compiles. The method with the proper syntax is

template<typename retval_t>
const retval_t obj2_t::getProperty(
        const obj_t& obj,
        const retval_t (obj2_t::*fProp)(const vec_t&, const string&, const int),
        const retval_t (obj_t::*fAggregate)(const retval_t&) const,
        const vec_t& vec,
        const string& s,
        const int i)
{
    const retval_t retval = getPropertySingle<retval_t>(fProp, vec, s, i);
    return (obj.*fAggregate)(retval);
};

An example caller function would perhaps be

const int obj2_t::getX(
        const obj_t& obj,
        const vec_t& vec,
        const string& s,
        const int i)
{
    const int retval = getProperty<int>(obj, &obj2_t::getXSingle, &obj_t::AggregateX, vec, s, i);
    return retval;
};

Useful example here (for as long as it lasts).

Related