检查模板形参是否有随机访问迭代器
Checking if a template parameter have Random Access Iterator or not
我对元编程完全陌生,并且我有一些问题。我想写一个容器,它有不同的内部表示,如果传递的Container
有Random Access Iterator
,使用不同的算法。然而,我不知道如何检查它。
更新:现在我正在尝试以下内容:
template <typename Container>
struct HaveRandomAccessIterator
{
typedef char yes[1];
typedef char no[2];
template <typename C>
static yes& test (typename std::random_access_iterator_tag*);
template <typename>
static no& test (...);
static const bool value = sizeof(test<std::iterator_traits<typename Container::iterator*>::iterator_category*>(0)) == sizeof(yes);
};
然而,它给我std::list的真值,我得到编译错误,因为在这种情况下,我使用了操作符[]
谁能告诉我怎样才能正确地检查它?
您的HaveRandomAccessIterator
模板过于复杂,有更简单的方法来实现相同的结果。
根据迭代器类型改变算法的一种标准方法是tag-dispatch:
//First, a helper type alias
template<typename Container>
using IteratorCategoryOf =
typename std::iterator_traits<typename Container::iterator>::iterator_category;
template<typename Container>
void algorithm(Container &c, std::forward_iterator_tag) {
//do generic version of algorithm
}
template<typename Container>
void algorithm(Container &c, std::random_access_iterator_tag) {
//do random-access version of algorithm
}
template<typename Container>
void algorithm(Container &c) {
algorithm(
c,
IteratorCategoryOf<Container>());
}
或者,您可以通过std::enable_if
使用SFINAE。我怀疑这是你的目标,但HaveRandomAccessIterator
可以用std::is_base_of
来写,这要简单得多:
template<typename Container>
using HaveRandomAccessIterator =
std::is_base_of<
std::random_access_iterator_tag,
IteratorCategoryOf<Container>>;
template<
typename Container,
typename std::enable_if<!HaveRandomAccessIterator<Container>::value>::type * = nullptr>
void algorithm(Container &c) {
//do generic version of algorithm
}
template<
typename Container,
typename std::enable_if<HaveRandomAccessIterator<Container>::value>::type * = nullptr>
void algorithm(Container &c) {
//do random-access version of algorithm
}
如果需要c++ 03兼容性,您可以使用继承而不是类型混叠,以及std::enable_if
和std::is_base_of
的boost对应项。
应该是:
static yes& test (typename std::iterator_traits<typename C::iterator*>::random_access_iterator_tag*);
SFINAE是这样工作的。
同时,我发现下面的语句更优雅:
struct yes{};
struct no {};
enum { value = std::is_same<yes, [test-here]>::value };
相关文章:
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?
- 如何为我的容器实现随机访问迭代器?
- 对于C++随机访问迭代器(矢量迭代器),迭代器之间的差异是如何计算的?
- 对于随机访问迭代器(矢量迭代器),迭代器C++样式指针吗?
- Deque 中元素的随机访问如何提供恒定的时间复杂度?
- C++ STL 数据结构常时按索引推送/弹出/随机访问,并具有指向元素的可靠指针
- SFINAE - 检测类型 T 是指针、数组还是带有随机访问运算符的容器,以及给定的值类型
- 随机访问迭代器:我错过了什么?
- 随机访问元组向量中的元组值
- 有没有办法在C++中制作无锁"counter"随机访问迭代器?
- 当 95% 情况下的值为 0 或 1 时,对非常大的数组进行随机访问的任何优化
- 如何确保函数模板的参数是随机访问迭代器
- C++基于现有随机访问迭代器的反向迭代器
- C++ 写入随机访问文件
- 如何实现随机访问迭代器的"less than operator"?
- 随机访问迭代器和Deque
- 如何创建一个随机访问式的Rreference以访问.RC文件中定义的资源
- 在链表上实现随机访问迭代器
- 随机访问文件格式,用于分层组织的二进制文件和文本文件