模板函数依赖于非类型参数
Template function dependent on non-type parameter
是否可以基于非类型参数定义重载模板函数?
以下情况:
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
的 return 值?
例如:
template<> uint32_t SetupMem<4>(){}
template<> uint64_t SetupMem<8>(){}
以便 TemplateCaller()
不会使用所需的模板参数显式调用 SetupMem
(从而避免类似:SetupMem<uint64, sizeof(size_t)>();
)?欢迎使用 C++11 的可能解决方案:)
你可以写一个类型特征:
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
}
只需使用简单的函数重载和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<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
的 return 值?
例如:
template<> uint32_t SetupMem<4>(){}
template<> uint64_t SetupMem<8>(){}
以便 TemplateCaller()
不会使用所需的模板参数显式调用 SetupMem
(从而避免类似:SetupMem<uint64, sizeof(size_t)>();
)?欢迎使用 C++11 的可能解决方案:)
你可以写一个类型特征:
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
}
只需使用简单的函数重载和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>{});
}