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();
}
Edit
Now since you've edited your question to specify that each of the passed arguments will have their own getter, you can use the following code.
Solution 1
Here we make use of pointer to member function as the second argument to the function template.
#include <iostream>
#include<string>
struct Name
{
bool valid()
{
return true;
}
int value ()
{
return 5;
}
};
struct Server1
{
Name getX()
{
std::cout<<"getX called"<<std::endl;
return Name();
}
};
struct Server2
{
Name getY()
{
std::cout<<"getY called"<<std::endl;
return Name();
}
};
template<typename ParamX, typename RType>
//--vvvv---------------------->auto type deduction
auto funcX(ParamX param,RType (ParamX::*callable)()){
std::cout<<"funcX called"<<std::endl;
auto result = ((param.*callable)());
// check result is valid
if(!result.valid()){
// print a log message for ParamX
// add appropriate return statement if needed
}
return result.value();
}
int main()
{
funcX(Server1(), &Server1::getX);
funcX(Server2(), &Server2::getY);
return 0;
}
Demo
The output of the above is:
funcX called
getX called
funcX called
getY called
Solution 2
This is a variation of solution 1 above. Here the second argument of the function template is taken as a reference to const.
#include <iostream>
#include<map>
#include<string>
#include<vector>
struct Name
{
bool valid()
{
return true;
}
int value ()
{
return 5;
}
};
struct Server1
{
Name getX()
{
std::cout<<"getX called"<<std::endl;
return Name();
}
};
struct Server2
{
Name getY()
{
std::cout<<"getY called"<<std::endl;
return Name();
}
};
template<typename ParamX, typename Callable>
//--vvvv---------------------->auto type deduction
auto funcX(ParamX param, const Callable& callable){
std::cout<<"funcX called"<<std::endl;
auto result = (param.*callable)();
// check result is valid
if(!result.valid()){
// print a log message for ParamX
// add appropriate return statement if needed
}
return result.value();
}
int main()
{
funcX(Server1(), &Server1::getX);
funcX(Server2(), &Server2::getY);
return 0;
}
Demo