【发布时间】:2014-10-13 08:32:44
【问题描述】:
我正在编写一个类IteratorIterable,它包装了一个容器类(一个带有begin() 和end() 方法返回一些迭代器的类),以便可以迭代被包装类的迭代器。这个想法基于this post。我的代码如下所示(为简洁起见,省略了一些方法):
template <class T>
class IteratorIterable
{
private:
T& container;
public:
typedef decltype(container.begin()) BackendIterator;
public:
class IteratorIterator
{
public:
IteratorIterator() : it() {}
IteratorIterator(BackendIterator it) : it(it) {}
IteratorIterator(const IteratorIterator& other) : it(other.it) {}
IteratorIterator& operator=(const IteratorIterator& other) { if (&other == this) return *this; it = other.it; return *this; }
BackendIterator operator*() const { return it; }
const BackendIterator* operator->() const { return ⁢ }
bool operator==(const IteratorIterator& other) { return it == other.it; }
bool operator !=(const IteratorIterator& other) { return it != other.it; }
IteratorIterator operator+(size_t n) { return IteratorIterator(it + n); }
IteratorIterator& operator++() { ++it; return *this; }
IteratorIterator operator++(int) { IteratorIterator cpy(*this); ++(*this); return cpy; }
private:
BackendIterator it;
};
public:
IteratorIterable(T& container) : container(container) {}
IteratorIterator begin() const { return IteratorIterator(container.begin()); }
IteratorIterator end() const { return IteratorIterator(container.end()); }
};
template <class T>
IteratorIterable<T> ItIt(T& container)
{
return IteratorIterable<T>(container);
}
这里的问题是,IteratorIterator 中的operator+() 方法只对随机访问BackendIterator 有效,否则后端没有定义加法运算符。我希望我的 IteratorIterator 仅在后端支持时才提供此方法。
考虑这个示例代码:
typedef list<int> Cont;
Cont vec = {1, 2, 3, 4, 5, 6, 7, 8, 9};
IteratorIterable<Cont> itb(vec);
IteratorIterable<Cont>::IteratorIterator beg = itb.begin();
IteratorIterable<Cont>::IteratorIterator it = beg;
it++;
//it = beg+1;
printf("%d\n", **it);
使用it++ 行时编译得很好,但是 - 正如预期的那样 - 使用it = beg+1 行失败,因为list<int>::iterator 不是随机访问。我想这是因为如果我实际上不实例化 IteratorIterator::operator+(),编译器不会关心。
我知道模板只允许对某些模板参数有效,但这里 class 是模板化的,而不是 method。当该方法从未用于此特定实例化时,实例化其中一个方法无效的类模板是否正确? GCC 和 Clang 没有抱怨,但按照 C++ 标准是否正确?
【问题讨论】: