如何解决一种值类型的容器迭代器模板
你之前帮助过我,所以我再次提出另一个问题,希望得到答案。
我有一个处理一系列 master
值的函数。我对函数定义的最初尝试是
std::complex<float>
但这仅适用于向量,不适用于 C 样式数组、std::arrays、范围等。
经过一番摆弄、大量的谷歌和一点点运气,我设法构建了这个:
// Example 1
using namespace std; // not in original code
Errc const& process(vector<complex<float>>::iterator begin,vector<complex<float>>::iterator end);
我什至不确定这是否有效,但至少可以编译。我认为它所做的是定义一个函数来处理具有任意值类型的任何容器。这将是一个问题,因为我只能处理 std::complex (或者可能是类似的复杂浮点值)而不是 std::string 例如。
我想做什么:
// 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);
但这显然不是这样做的方法。我大约有 60% 的把握确定我在示例 2 中也搞砸了一些事情。
非常感谢任何帮助或提示。谢谢
解决方法
您的示例 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::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>>);
//...
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。