I have a group of functions which perform similar action on different input parameter classes ParamX, ParamY, ParamZ. They have a general form like:
Result funcX(ParamX param){
auto result = param.getX();
// check result is valid
if(!result.valid()){
// print a log message for ParamX
return {};
}
return result.value();
}
Result is a templated struct like Result<ParamX>, based on the type of input parameter class ParamX.
So given I have several different functions funcX, funcY, funcZ, each acting on ParamX, ParamY, ParamZ separately, how do I convert this into a single template function?
CodePudding user response:
given I have several different functions funcX, funcY, funcZ, each acting on ParamX, ParamY, ParamZ separately, how do I convert this into a single template function?
You can make use of function templates and auto type deduction(using the auto type specifier in the return type) as shown below:
template<typename ParamX>
//--vvvv---------------------->auto type deduction
auto funcX(ParamX param){
auto result = param.getX();
// check result is valid
if(!result.valid()){
// print a log message for ParamX
// add appropriate return statement if needed
}
return result.value();
}
CodePudding user response:
Assuming this was requirements above:
template <typename TParam,typename TResult>
TResult funcX(TParam param){
auto result = param.getX();
// check result is valid
if(!result.valid()){
// print a log message for ParamX
return {};
}
return result.value();
}
Note if you want to generalize coordinate you can invoke template compile time polymorpism by implying a member(in this case its getx of tparam). If you want to generalize u just need to agree on a name. Alternatively if performance not important u can do runtime polymorpism via a virtual member. This doesnt require a template.
If u want a complicated template example have a look at my non blocking network templates here:
CodePudding user response:
It depends on the properties of ParamX, Result<ParamX>, and the other types to some extent.
But, assuming (since you haven't specified)
- You have a templated type
Resultsuch thatResult<ParamX>is the result corresponding to aParamX, andResult<ParamY>is the result corresponding to aParamY Result<ParamX>is default constructible (so it will be constructed inreturn {}for a function that returnsResult<ParamX>;ParamX,ParamY, etc all have a member functiongetX();- The return type of that
getX()function is implicitly convertible toResult<ParamX>; - The return type of that
getX()function has a member function namedvalid()that returns an integral type (where a zero orfalsereturn indicates invalid);
You might do something like
template<class Param> Result<Param> func(Param param)
{
auto result = param.getX();
// check result is valid
if(!result.valid())
{
// print a log message
return {};
}
return result.value();
}
Then, to use that function you might do;
ParamX px;
Result<ParamX> result = Result(px); // Result(px) is equivalent to Result<ParamX>(px)
auto result2 = Result(px); // compiler will deduce the type of result2 as Result<ParamX>
ParamY py;
Result<ParamY> result = Result(py); // Result(py) is equivalent to Result<ParamY>(py)
Note I'm making a lot of assumptions in the above, to fill in information you have not provided. You need to make a similar set in your code and (more importantly) ensure they are true.
