简体   繁体   English

模板功能取决于非类型参数

[英]Template function dependent on non-type parameter

Is it somehow possible to define an overloaded template function based on a non-type parameter? 是否可以基于非类型参数定义重载模板函数?

following situation: 以下情况:

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

now is it somehow possible to change the return value of SetupMem based on the non-type parameter? 现在可以通过非类型参数更改SetupMem的返回值吗? eg: 例如:

template<> uint32_t SetupMem<4>(){}
template<> uint64_t SetupMem<8>(){}

So that TemplateCaller() does not explicitly calls SetupMem with the desired template parameter (so avoiding something like: SetupMem<uint64, sizeof(size_t)>(); )? 这样, TemplateCaller()不会使用所需的模板参数显式调用SetupMem (因此避免类似: SetupMem<uint64, sizeof(size_t)>(); )吗? Possible solutions upto C++11 are welcome :) 欢迎使用C ++ 11之前的可能解决方案:)

You can write a type trait: 您可以编写类型特征:

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
}

online compiler 在线编译器

Just use simple function overloading and std::integral_constant : 只需使用简单的函数重载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)
}

You can introduce a template type alias for readability: 您可以引入模板类型别名以提高可读性:

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

live example on wandbox.org wandbox.org上的实时示例


If your compiler doesn't support integral_constant , all you need to do is define it yourself: 如果您的编译器不支持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>{});
}

live example on wandbox.org wandbox.org上的实时示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM