首页 > 解决方案 > 一种值类型的容器迭代器模板

问题描述

你以前帮助过我,所以我再次提出另一个问题,希望得到答案。

我有一个处理一系列std::complex<float>值的函数。我最初尝试定义函数是

// Example 1
using namespace std; // not in original code
Errc const& process(vector<complex<float>>::iterator begin, vector<complex<float>>::iterator end);

然而,这仅适用于向量,而不适用于 C 样式数组、std::arrays、范围等。

经过一番摆弄,大量的谷歌和一点点运气,我设法构建了这个:

// Example 2
using namespace std; // not in original code
template<
    template<typename T> class C,
    typename T,
    typename C<T>::iterator iterator
    >
Errc const& process(typename C<T>::iterator begin, typename C<T>::iterator end);

我什至不确定这是否有效,但至少可以编译。我认为它的作用是定义一个处理具有任意值类型的任何容器的函数。这将是一个问题,因为我只能处理 std::complex (或者可能是类似的复杂浮点值),但不能处理 std::string 例如。

我想做的事:

// Example 3
using namespace std; // not in original code
template<
    template<typename complex<float>> class C,
    typename C<complex<float>>::iterator iterator
    >
Errc const& process(typename C<complex<float>>::iterator begin, typename C<complex<float>>::iterator end);

但这显然不是做到这一点的方法。我有大约 60% 的把握在示例 2 中也搞砸了一些事情。

非常感谢任何帮助或提示。谢谢

标签: c++templatesiteratorcontainers

解决方案


您的示例 2 几乎是正确的

template<
    template<typename T> class C,
    typename T,
    typename C<T>::iterator iterator // That is wrong
    >
Errc const& process(typename C<T>::iterator begin, typename C<T>::iterator end);

它应该是:

template<template <typename> class C, typename T>
Errc const& process(typename C<T>::iterator begin, typename C<T>::iterator end);

但问题是C/T是不可推论的,你必须这样称呼它:

process<std::vector, std::complex<float>>(v.begin(), v.end());

并且C-array两者std::array都不匹配template <typename> class C(并且std::vector也有默认分配器:-/)

更简单的是

template<typename Iterator>
Errc const& process(Iterator begin, Iterator end);

可能有一些 SFINAE

template <typename Iterator,
          std::enable_if_t<std::is_same_v<std::complex<float>,
                                          std::iterator_traits<Iterator>::value_type>, int> = 0>
Errc const& process(Iterator begin, Iterator end);

或 C++20 要求:

template <typename Iterator>
Errc const& process(Iterator begin, Iterator end)
requires (std::is_same_v<std::complex<float>, std::iterator_traits<Iterator>::value_type);

如果您只想要连续的序列,您可以使用std::span

Errc const& process(std::span<std::complex<float>)

推荐阅读