在可变参数模板函数中接受int和class?

Xun*_*nie 3 c++ templates variadic-templates

这一功能的摔跤模板证明是超出我的.


我想要的是:

一个函数,它生成与以下任何容器中给定的浮点类型相同的浮点类型:

  • vector<ANY_FLOAT_TYPE>
  • array<ANY_FLOAT_TYPE, N>

(当然,我愿意让它接受更多容器!)


问题:

问题在于array <>接受一个整数作为其第二个模板参数,而vector <>接受该位置的分配器.如何编写一个可以接受单个参数的类型名和整数的模板化函数?或者这是继续编写此函数的错误方法吗?

我可以复制粘贴并写两次函数,包括vector<>s和array<>s,但这不是解决方案......

template <typename FT, typename CONT_T, typename... Ts>
FT float_sum( CONT_T<FT, Ts...> xs ) {

    // WARNING: not an accurate summation algorithm!
    return accumulate( xs.begin(), xs.end(), 0 );

    //////////////
    static_assert( is_floating_point<FT>::value, "sum() only accepts floating point types." );
}
Run Code Online (Sandbox Code Playgroud)

mir*_*ulo 7

只需将整个容器作为模板参数,然后使用value_type,它是所有Container类型的接口的一部分.就像是

template <typename Container>
auto sum(Container const &container)
    -> typename Container::value_type
{
  using value_type = typename Container::value_type;
  static_assert(std::is_floating_point<value_type>::value, 
                "only for floating types");

  return std::accumulate(container.cbegin(), container.cend(), value_type{});
}
Run Code Online (Sandbox Code Playgroud)

另外,如果你决定你最终还是要总结与使用一些其他的专业化非浮动类型的容器,你可以选择放弃静态断言赞成SFINAEstd::enable_if,或(由C++ 20)概念.使用GCC中的概念TS > = 6:

template <typename Container>
auto sum(Container const &container)
requires 
    std::is_floating_point<typename Container::value_type>::value    
{
  using value_type = typename Container::value_type;
  return std::accumulate(container.cbegin(), container.cend(), value_type{});  
}
Run Code Online (Sandbox Code Playgroud)