【问题标题】:Recursive template function with multiple types具有多种类型的递归模板函数
【发布时间】:2013-12-09 08:43:23
【问题描述】:

我正在尝试编写计算两个向量的标量积的函数。 这是代码,它可以工作。

    template <int N> 
    int scalar_product (std::vector<int>::iterator a, 
                        std::vector<int>::iterator b) {
        return (*a) * (*b) + scalar_product<N - 1>(a + 1, b + 1);
    }

    template <>
    int scalar_product<0>(std::vector<int>::iterator a,
                          std::vector<int>::iterator b) {
        return 0;
    }

但问题出在这里——我想用模板类型替换这个迭代器,这样函数的签名就会像这样

    template <typename Iterator ,int N> 
    int scalar_product (Iterator a, Iterator b) {
        return (*a) * (*b) + scalar_product<N - 1>(a + 1, b + 1);
    }

    template <typename Iterator>
    int scalar_product<0>(Iterator a,
                          Iterator b) {
        return 0;
    }

但这不起作用 - 我收到编译错误 C2768:非法使用显式模板参数。这看起来很傻,但我不知道应该改变什么来避免这个错误。

【问题讨论】:

  • 为什么不使用std::inner_product?内联循环对您来说如此重要吗?
  • @Nim 感谢您的链接 - 它有帮助。
  • @gwiazdorr 实际上,它只是 codereview 任务的一部分,因此它期望使用模板作为内联循环。
  • 好吧,您仍然可以为此使用免费功能。看看我的回答。

标签: c++ templates recursion


【解决方案1】:

实际上,您不必使用类型 - 我发现它们非常麻烦并且它们的语义不同。您不能部分特化一个函数,但您可以重载它们并通过提供默认参数值使它们表现得像特化:

#include <type_traits>

template <typename Iterator>
int scalar_product(Iterator a, Iterator b, std::integral_constant<int, 0> = std::integral_constant<int, 0>()  ) 
{
    return 0;
}

template <int N, typename Iterator> 
int scalar_product (Iterator a, Iterator b, std::integral_constant<int, N> = std::integral_constant<int, N>() ) 
{
    return (*a) * (*b) + scalar_product(a + 1, b + 1, std::integral_constant<int, N-1>() );
}

int foo()
{
    int a[] = { 1, 2, 3, 4 };
    int b[] = { 1, 1, 1, 1 };
    return scalar_product<4>(a, b); // returns 10
}

【讨论】:

    【解决方案2】:

    (AFAIK) 不支持函数模板的部分特化,要获得此功能,您需要稍作不同,例如:

    template <int N>
    struct scalar
    {
      template <typename Iterator>
      static int product(Iterator a, Iterator b)
      { (*a) * (*b) + scalar<N - 1>::product(a + 1, b + 1); }
    };
    
    template <>
    struct scalar<0>
    {
      template <typename Iterator>
      static int product(Iterator a, Iterator b)
      { return 0; }
    };
    

    【讨论】:

      猜你喜欢
      • 2018-12-06
      • 2021-12-28
      • 1970-01-01
      • 1970-01-01
      • 2019-07-20
      • 1970-01-01
      • 2017-12-22
      • 2010-12-17
      • 1970-01-01
      相关资源
      最近更新 更多