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:
- 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. - 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.