Функция шаблона зависит от нетипичного параметра

Можно ли как-то определить перегруженную функцию шаблона на основе нетипичного параметра?

следующая ситуация:

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>{});
}

живой пример на wandbox.org


Если ваш компилятор не поддерживает 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>{});
}

живой пример на wandbox.org

Вы можете написать черту типа:

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
}

онлайн компилятор

Другие вопросы по тегам