在处理模板时,如何避免在函数头和函数体中两次声明相同的类型



我编写了这个函数,它返回两个迭代器分隔的范围内值的平均值:

template<class InputIterator>
typename std::decay<decltype(*std::declval<InputIterator>())>::type mean (InputIterator first, InputIterator last) {
  return std::accumulate(first, last, typename std::decay<decltype(*std::declval<InputIterator>())>::type ()) / std::distance(first, last);
}

从迭代器推导出在内部使用和返回的值类型。由于类型演绎的语法相当重,我想知道是否有一种方法可以避免使用它两次。

我知道我可以添加第二个模板参数并将其默认值设置为值类型,但我不相信,因为可以指定不同的值类型,我希望排除这种可能性。

您可以使用别名模板为yourType创建一个泛型类型定义

template<class InIt>
using yourType = typename decay<decltype(*declval<InIt>())>::type;
template<class InIt>
yourType<InIt> mean(InIt first, InIt last) 
{
    return accumulate(first, last, yourType<InIt>()) / distance(first, last);
}

现场演示

为避免用户更改默认类型,您可以添加可变模板

template <typename InputIterator,
        typename...,
        typename Type = typename std::decay<decltype(*std::declval<InputIterator>())>::type
    >
Type mean (InputIterator first, InputIterator last) {
    return std::accumulate(first, last, Type()) / std::distance(first, last);
}

,甚至更安全,以避免向mean提供更多的模板参数。

template <typename InputIterator,
        typename...DummyTs,
        typename Type = typename std::decay<decltype(*std::declval<InputIterator>())>::type,
        typename = typename std::enable_if<sizeof...(DummyTs) == 0>::type
    >
Type mean (InputIterator first, InputIterator last) {
    return std::accumulate(first, last, Type()) / std::distance(first, last);
}

最新更新