Функция шаблона зависит от нетипичного параметра
Можно ли как-то определить перегруженную функцию шаблона на основе нетипичного параметра?
следующая ситуация:
template<uint8_t> void SetupMem();
template<> void SetupMem<4>()
{ /* some code */ }
template<> void SetupMem<8>()
{ /* some code */ }
void TemplateCaller()
{
// use the plattform-specific template function at compile-time
SetupMem<sizeof(size_t)>();
}
Теперь можно ли как-то изменить возвращаемое значение SetupMem
на основе нетипичного параметра? например:
template<> uint32_t SetupMem<4>(){}
template<> uint64_t SetupMem<8>(){}
Чтобы TemplateCaller()
не вызывает явно SetupMem
с желаемым параметром шаблона (поэтому избегая чего-то вроде: SetupMem<uint64, sizeof(size_t)>();
)? Возможные решения до C++11 приветствуются:)
2 ответа
Решение
Просто используйте простую функцию перегрузки и std::integral_constant
:
std::uint32_t SetupMem(std::integral_constant<int, 4>); // (0)
std::uint64_t SetupMem(std::integral_constant<int, 8>); // (1)
void TemplateCaller()
{
auto a = SetupMem(std::integral_constant<int, 4>{}); // calls (0)
auto b = SetupMem(std::integral_constant<int, 8>{}); // calls (1)
}
Вы можете ввести псевдоним типа шаблона для удобства чтения:
template <int X>
using ic = std::integral_constant<int, X>;
std::uint32_t SetupMem(ic<4>);
std::uint64_t SetupMem(ic<8>);
void TemplateCaller()
{
auto a = SetupMem(ic<4>{});
auto b = SetupMem(ic<8>{});
}
Если ваш компилятор не поддерживает integral_constant
все, что вам нужно сделать, это определить это самостоятельно:
template <int>
struct ic { };
std::uint32_t SetupMem(ic<4>);
std::uint64_t SetupMem(ic<8>);
void TemplateCaller()
{
auto a = SetupMem(ic<4>{});
auto b = SetupMem(ic<8>{});
}
Вы можете написать черту типа:
template<::std::size_t x_Size> class
t_IntegralFromSize;
template<> class
t_IntegralFromSize<4> final
{
public: using type = ::std::uint32_t;
};
template<> class
t_IntegralFromSize<8> final
{
public: using type = ::std::uint64_t;
};
template<::std::size_t x_Size> typename t_IntegralFromSize<x_Size>::type
SetupMem();
template<> t_IntegralFromSize<4>::type
SetupMem<4>()
{ /* some code */ }
template<> t_IntegralFromSize<8>::type
SetupMem<8>()
{ /* some code */ }
void TemplateCaller()
{
// use the plattform-specific template function at compile-time
SetupMem<sizeof(size_t)>(); // works without changes
}