[英]Function template accepting nothing less than a bidirectional iterator or a pointer
I need a function template that accepts two iterators that could be pointers. 我需要一个函数模板,它接受两个可能是指针的迭代器。 If the two arguments are random_access iterators I want the return type to be an object of
如果两个参数是random_access迭代器,我希望返回类型是一个对象
std::iterator<random_access_iterator_tag, ...>
type std::iterator<random_access_iterator_tag, ...>
类型
else a 否则一个
std::iterator<bidirectional_iterator_tag, ...>
type. std::iterator<bidirectional_iterator_tag, ...>
类型。
I also want the code to refuse compilation if the arguments are neither a bidirectional iterator, nor a pointer. 如果参数既不是双向迭代器也不是指针,我也希望代码拒绝编译。 I cannot have dependency on third party libraries eg Boost
我不能依赖第三方库,例如Boost
Could you help me with the signature of this function so that it accepts bidirectional iterators as well as pointers, but not say input_iterator, output_iterator, forward_iterators. 你能帮助我使用这个函数的签名,以便它接受双向迭代器和指针,但不是说input_iterator,output_iterator,forward_iterators。
One partial solution I can think of is the following 我能想到的一个部分解决方案如下
template<class T>
T foo( T iter1, T iter2) {
const T tmp1 = reverse_iterator<T>(iter1);
const T tmp2 = reverse_iterator<T>(iter2);
// do something
}
The idea is that if it is not bidirectional the compiler will not let me construct a reverse_iterator from it. 我的想法是,如果它不是双向的,编译器就不会让我从中构造一个reverse_iterator。
Here's an example with enable_if
based on iterator tags. 这是一个基于迭代器标记的
enable_if
示例。 The substitution fails if the given T doesn't have a iterator_category
typedef and so that overload isn't considered during overload resolution. 如果给定的T没有
iterator_category
typedef,则替换失败,因此在重载解析期间不考虑重载。
Since you can't use C++11, see the reference pages for enable_if
and is_same
to see how you can implement it by yourself. 由于您无法使用C ++ 11,请参阅
enable_if
和is_same
的参考页面,了解如何is_same
实现它。
#include <iterator>
#include <type_traits>
#include <iostream>
#include <vector>
#include <list>
template<typename T>
typename
std::enable_if<
std::is_same<
typename T::iterator_category,
std::bidirectional_iterator_tag
>::value,
T
>::type
foo(T it)
{
std::cout << "bidirectional\n";
return it;
}
template<typename T>
typename
std::enable_if<
std::is_same<
typename T::iterator_category,
std::random_access_iterator_tag
>::value,
T
>::type
foo(T it)
{
std::cout << "random access\n";
return it;
}
// specialization for pointers
template<typename T>
T* foo(T* it)
{
std::cout << "pointer\n";
return it;
}
int main()
{
std::list<int>::iterator it1;
std::vector<int>::iterator it2;
int* it3;
std::istream_iterator<int> it4;
foo(it1);
foo(it2);
foo(it3);
//foo(it4); // this one doesn't compile, it4 is an input iterator
}
Live example . 实例 。
As per @JonathanWakely's comment, we can get rid of specialization for pointers if we use std::iterator_traits . 根据@ JonathanWakely的评论,如果我们使用std :: iterator_traits ,我们可以摆脱指针的特化。 The
typename T::iterator_category
part then becomes 然后,
typename T::iterator_category
部分成为
typename std::iterator_traits<T>::iterator_category
a bit simpler than previous answer, no dependency on std::enable_if: 比以前的答案简单一点,不依赖于std :: enable_if:
namespace detail
{
template<class T>
T do_foo(T iter1, T iter2, std::random_access_iterator_tag t)
{
cout << "do_foo random_access" << endl;
return iter1;
}
template<class T>
T do_foo(T iter1, T iter2, std::bidirectional_iterator_tag t)
{
cout << "do_foo bidirectional" << endl;
return iter1;
}
}
template<class T>
void foo(T iter1, T iter2)
{
typename std::iterator_traits<T>::iterator_category t;
detail::do_foo(iter1, iter2, t);
}
int main (int argc, const char * argv[])
{
std::vector<int> v;
foo(v.begin(), v.end());
std::list<int> l;
foo(l.begin(), l.end());
return 0;
}
The solution also supports other iterator_categories derived from std::random_access_iterator_tag or std::bidirectional_iterator_tag (should there be any), while std::same<> checks for strict category equality. 该解决方案还支持从std :: random_access_iterator_tag或std :: bidirectional_iterator_tag派生的其他iterator_categories(如果有的话),而std :: same <>检查严格类别相等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.