根据模板参数不等式执行不同的功能

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,但通常这可能是一种替代方法。