私はインターフェイスにプログラミングしており、その内容を一般化された方法でやり取りしたいと考えています。したがって、一般的に、私のインターフェイスには次のようなプロトタイプがあります。
class Interface
{
public:
class Iterator;
virtual Interface::Iterator* begin() = 0;
virtual Interface::Iterator* end() = 0;
class Iterator
{
public:
virtual const Iterator* operator++() = 0;
virtual bool operator!=(const Iterator& i) = 0;
};
};
以下は、単純な特殊化の例です。
class Derived : public Interface
{
public:
Derived() : array {2, 0, 1, 5, 4, 3} {};
Iterator* begin() { return new Derived::IterDerived(0);};
Iterator* end() { return new Derived::IterDerived(6);};
int array[6];
public:
class IterDerived : public Interface::Iterator
{
public:
IterDerived(int i) {pos = i;};
IterDerived(IterDerived&& i) {pos = i.pos;};
const Interface::Iterator* operator++() override { ++pos; return this;};
bool operator!=(const Interface::Iterator& i) { return pos != dynamic_cast<const Derived::IterDerived&>(i).pos;};
int position() { return pos;};
private:
int pos;
};
};
ここまでは順調ですね。ここで、新しい標準 (c++11) で指定されているように、新しい for 範囲を使用してコンテンツを反復処理できるコードを書きたいと思います。実際のインターフェイスでは getter メソッドを提供するので、dynamic_cast を使用する必要はありません。すなわち:
int main()
{
Interface *a = new Derived();
for(auto i : a)
std::cout << dynamic_cast<Derived*>(a)->array[dynamic_cast<Derived::IterDerived*>(i.get())->position()] << " ";
std::cout << std::endl;
}
しかし、このコードはコンパイルされません。コンパイルするには、次の形式でマクロを使用する必要があります。
#define FOR_ITERATOR(iter, object) \
for(std::unique_ptr<Interface::Iterator> iter((object)->begin()), \
iter##end((object)->end()); \
*iter != *(iter##end); ++(*iter))
for 範囲の場所。ステートメントに新しい範囲を使用する機会はありますか? または、この種のマクロを使用する必要がありますか?