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
Result
such 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 orfalse
return 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.