Home > OS >  Convert a group of C functions into C Template
Convert a group of C functions into C Template

Time:04-03

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:

https://bitbucket.org/ptroen/crossplatformnetwork/src/master/OSI/Application/Stub/HTTPSServer/httpsserver.cc

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 that Result<ParamX> is the result corresponding to a ParamX, and Result<ParamY> is the result corresponding to a ParamY
  • Result<ParamX> is default constructible (so it will be constructed in return {} for a function that returns Result<ParamX>;
  • ParamX, ParamY, etc all have a member function getX();
  • The return type of that getX() function is implicitly convertible to Result<ParamX>;
  • The return type of that getX() function has a member function named valid() that returns an integral type (where a zero or false 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.

  • Related