一种值类型的容器迭代器模板
Container Iterator Template for one value type
你之前帮助过我,所以我又来了一个问题,希望得到答案。
我有一个函数可以处理一系列 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、范围等
经过一些摆弄、很多 Google 和一点点运气,我设法构建了这个:
// 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 中也搞砸了。
非常感谢任何帮助或提示。谢谢
您可以使用 std::iterator_traits
并将迭代器的 value_type
与您想要支持的类型进行比较:
#include <iterator>
#include <type_traits>
template<class It, std::enable_if_t<
std::is_same_v<class std::iterator_traits<It>::value_type,
std::complex<float>
>, int> = 0>
Errc const& process(It begin, It end) {
//...
}
选择:
template<class It>
std::enable_if_t<std::is_same_v<class std::iterator_traits<It>::value_type,
std::complex<float>>, Errc const&>
process(It begin, It end) {
//...
}
如果不需要SFINAE,static_assert
:
template<class It>
Errc const& process(It begin, It end) {
static_assert(
std::is_same_v<class std::iterator_traits<It>::value_type,
std::complex<float>>);
//...
}
你的例子 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>)
你之前帮助过我,所以我又来了一个问题,希望得到答案。
我有一个函数可以处理一系列 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、范围等
经过一些摆弄、很多 Google 和一点点运气,我设法构建了这个:
// 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 中也搞砸了。
非常感谢任何帮助或提示。谢谢
您可以使用 std::iterator_traits
并将迭代器的 value_type
与您想要支持的类型进行比较:
#include <iterator>
#include <type_traits>
template<class It, std::enable_if_t<
std::is_same_v<class std::iterator_traits<It>::value_type,
std::complex<float>
>, int> = 0>
Errc const& process(It begin, It end) {
//...
}
选择:
template<class It>
std::enable_if_t<std::is_same_v<class std::iterator_traits<It>::value_type,
std::complex<float>>, Errc const&>
process(It begin, It end) {
//...
}
如果不需要SFINAE,static_assert
:
template<class It>
Errc const& process(It begin, It end) {
static_assert(
std::is_same_v<class std::iterator_traits<It>::value_type,
std::complex<float>>);
//...
}
你的例子 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>)