Преобразование группы функций C++ в шаблон C++
У меня есть группа функций, которые выполняют аналогичные действия для разных классов входных параметров ParamX, ParamY, ParamZ. Они имеют общий вид:
Result funcX(ParamX param){
auto result = param.getX(); // param.getY() in case of ParamY
// check result is valid
if(!result.valid()){
// print a log message for ParamX
return {};
}
return result.value();
}
Результатом является шаблонная структура, например
Result<ParamX>
, в зависимости от типа класса входных параметров ParamX.
Также обратите внимание, что каждый параметр будет вызывать совершенно другую функцию.
param.getX()
,
param.getY()
,
param.getZ()
Итак, учитывая, что у меня есть несколько разных функций
funcX
,
funcY
,
funcZ
, каждая из которых действует на ParamX, ParamY, ParamZ отдельно, как мне преобразовать это в одну функцию шаблона?
Также учтите, что в будущем любой разработчик может сделать еще один
ParamA
,
ParamB
.... класс с разными
getA()
,
getB()
методы, поэтому ничего не исправлено.
3 ответа
Предполагая, что это были требования выше:
template <typename TParam,typename TResult>
TResult funcX(параметр TParam){
автоматический результат = param.getX();
// check result is valid
if(!result.valid()){
// print a log message for ParamX
return {};
}
return result.value();
}
Обратите внимание, что если вы хотите обобщить координаты, вы можете вызвать полиморфизм времени компиляции шаблона, подразумевая член (в данном случае это getx tparam). Если вы хотите обобщить, вам просто нужно договориться об имени. В качестве альтернативы, если производительность не важна, вы можете использовать полиморфизм во время выполнения через виртуальный член. Для этого не требуется шаблон.
Если вам нужен сложный пример шаблона, посмотрите мои неблокирующие сетевые шаблоны здесь:
Это зависит от свойств , , и других типов в некоторой степени.
Но, предполагая (поскольку вы не указали)
- У вас шаблонный тип
Result
такой, что результат соответствует a , иResult<ParamY>
результат, соответствующий - является конструктивным по умолчанию (поэтому он будет построен в
return {}
для функции, которая возвращает ; -
ParamX
,ParamY
и т. д. все имеют функцию-член; - Тип возвращаемого значения этой функции неявно преобразуется в
Result<ParamX>
; - Тип возврата этого
getX()
функция имеет функцию-член с именемvalid()
который возвращает целочисленный тип (где ноль илиfalse
возврат указывает на недействительность);
Вы можете сделать что-то вроде
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();
}
Затем, чтобы использовать эту функцию, вы можете сделать;
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)
Обратите внимание, что я делаю много предположений в приведенном выше, чтобы заполнить информацию, которую вы не предоставили. Вам нужно сделать аналогичный набор в своем коде и (что более важно) убедиться, что они верны.
Я бы предложил встроить звонки в ,
getY
и т.д. в функции шаблона. Это имеет то преимущество, что его легко расширять, когда вы хотите добавить дополнительные типы.
ParamX
с.
// generic template declaration
template <typename Paramtype>
auto get(const ParamType& Param);
template <>
auto get(const ParamX& Param) { return Param.getX(); }
template <>
auto get(const ParamY& Param) { return Param.getY(); }
// etc...
template <typename Param>
auto Result<Param> func(Param param)
{
auto result = get(param);
// check result is valid
if(!result.valid())
{
// print a log message
return Result<Param>{};
}
return result.value();
}
Примечание: я предполагаю, что
getX
методы , поэтому параметр
get
является ссылкой. Если это не так, необходимо отрегулировать
const
например, используя универсальные ссылки .