根据模板参数不等式执行不同的功能
Execute different functions depending on template parameter disequation
这绝对是一个微不足道的问题,但我不知道该怎么做。
我有一个模板函数,比如说template <unsigned int N> void my_function()
。现在,我对 my_function
有两种不同的实现方式,如果 N
大于 100,则应使用第一种,如果 N
小于 100,则应使用另一种。
我试过这样使用 SFINAE:
template <unsigned int N, typename = enable_if <N >= 100> :: type> my_function()
{
// First implementation
}
template <unsigned int N, typename = enable_if <N < 100> :: type> my_function()
{
// Second implementation
}
但这是两次声明相同的函数。然后我尝试做类似
的事情
template <unsigned int N, bool = (N >= 100)> my_function();
然后用两个不同的布尔值实现这两个函数。没有成功,因为它是部分专业化。
然后我尝试将 N
包装为结构参数,并将 bool 包装在函数调用中,但它在特化 class 之前特化了一个成员函数,这是无法完成的。
有合理的方法吗?
试试这个:
#include <type_traits>
#include <iostream>
template <unsigned int N, typename std::enable_if <N >= 100> :: type* = nullptr>
void my_function()
{
std::cout << "N >= 100" << std::endl;
}
template <unsigned int N, typename std::enable_if <N < 100> :: type* = nullptr>
void my_function()
{
std::cout << "N < 100" << std::endl;
}
int main()
{
my_function<42>();
my_function<100>();
}
Template default parameters do not participate in the overload(因此 SFINAE 不适用)。另一方面,在上面的代码片段中,依赖模板非类型参数位于赋值的左侧,因此 SFINAE 开始了。
您可以在 return 上使用 SFINAE 类型:
template <unsigned int N>
enable_if_t<(N >= 100)> my_function()
{
// First implementation
}
template <unsigned int N>
enable_if_t<(N < 100)> my_function()
{
// Second implementation
}
目前,您只有 template <unsigned int N, typename T>
个具有不同默认类型的 T
。
对于部分专业化,您可以转发到结构:
template <unsigned int N, bool = (N >= 100)>
struct my_function_impl;
template <unsigned int N>
struct my_function_impl<N, true>
{
void operator () const { /* First implementation */}
};
template <unsigned int N>
struct my_function_impl<N, false>
{
void operator () const { /* Second implementation */}
};
template <unsigned int N>
void my_function() { my_function_impl<N>{}(); }
如果您出于某种原因不喜欢 enable_if,您可以随时发送标签:
#include <type_traits>
class low {};
class high {};
template <int N, class T>
void func(T, low)
{
// version for high N
}
template <int N, class T>
void func(T, high)
{
// version for low N
}
template <int N, class T>
void func(T val)
{
func<N>(val, std::conditional_t<(N>=100), high, low>{});
}
int main()
{
func<3>(3.14159); // low version
func<256>("Yo"); // high version
}
在这种情况下,我们可以将标签限制为简单的内容,例如 true_type 和 false_type,但通常这可能是一种替代方法。
这绝对是一个微不足道的问题,但我不知道该怎么做。
我有一个模板函数,比如说template <unsigned int N> void my_function()
。现在,我对 my_function
有两种不同的实现方式,如果 N
大于 100,则应使用第一种,如果 N
小于 100,则应使用另一种。
我试过这样使用 SFINAE:
template <unsigned int N, typename = enable_if <N >= 100> :: type> my_function()
{
// First implementation
}
template <unsigned int N, typename = enable_if <N < 100> :: type> my_function()
{
// Second implementation
}
但这是两次声明相同的函数。然后我尝试做类似
的事情template <unsigned int N, bool = (N >= 100)> my_function();
然后用两个不同的布尔值实现这两个函数。没有成功,因为它是部分专业化。
然后我尝试将 N
包装为结构参数,并将 bool 包装在函数调用中,但它在特化 class 之前特化了一个成员函数,这是无法完成的。
有合理的方法吗?
试试这个:
#include <type_traits>
#include <iostream>
template <unsigned int N, typename std::enable_if <N >= 100> :: type* = nullptr>
void my_function()
{
std::cout << "N >= 100" << std::endl;
}
template <unsigned int N, typename std::enable_if <N < 100> :: type* = nullptr>
void my_function()
{
std::cout << "N < 100" << std::endl;
}
int main()
{
my_function<42>();
my_function<100>();
}
Template default parameters do not participate in the overload(因此 SFINAE 不适用)。另一方面,在上面的代码片段中,依赖模板非类型参数位于赋值的左侧,因此 SFINAE 开始了。
您可以在 return 上使用 SFINAE 类型:
template <unsigned int N>
enable_if_t<(N >= 100)> my_function()
{
// First implementation
}
template <unsigned int N>
enable_if_t<(N < 100)> my_function()
{
// Second implementation
}
目前,您只有 template <unsigned int N, typename T>
个具有不同默认类型的 T
。
对于部分专业化,您可以转发到结构:
template <unsigned int N, bool = (N >= 100)>
struct my_function_impl;
template <unsigned int N>
struct my_function_impl<N, true>
{
void operator () const { /* First implementation */}
};
template <unsigned int N>
struct my_function_impl<N, false>
{
void operator () const { /* Second implementation */}
};
template <unsigned int N>
void my_function() { my_function_impl<N>{}(); }
如果您出于某种原因不喜欢 enable_if,您可以随时发送标签:
#include <type_traits>
class low {};
class high {};
template <int N, class T>
void func(T, low)
{
// version for high N
}
template <int N, class T>
void func(T, high)
{
// version for low N
}
template <int N, class T>
void func(T val)
{
func<N>(val, std::conditional_t<(N>=100), high, low>{});
}
int main()
{
func<3>(3.14159); // low version
func<256>("Yo"); // high version
}
在这种情况下,我们可以将标签限制为简单的内容,例如 true_type 和 false_type,但通常这可能是一种替代方法。