【问题标题】:Execute different functions depending on template parameter disequation根据模板参数不等式执行不同的功能
【发布时间】:2015-08-07 01:27:51
【问题描述】:

这绝对是一个微不足道的问题,但我不知道该怎么做。

我有一个模板函数,比如template <unsigned int N> void my_function()。现在,我对my_function 有两种不同的实现,如果N 大于例如100,则应使用第一种,如果N 小于此,则应使用另一种。

我尝试像这样使用 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,但它在专门化类之前专门化了成员函数,这是无法做到的。

有没有合理的方法来做到这一点?

【问题讨论】:

    标签: c++ templates c++11 sfinae


    【解决方案1】:

    试试这个:

    #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 不适用)。另一方面,在上面的 sn-p 中,依赖的模板非类型参数在赋值的左侧,所以 SFINAE 起作用了。

    【讨论】:

      【解决方案2】:

      如果你因为某种原因不喜欢 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,但通常这可能是另一种方法。

      【讨论】:

        【解决方案3】:

        您可以在返回类型上使用 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 &lt;unsigned int N, typename T&gt;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>{}(); }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-15
          相关资源
          最近更新 更多