テンプレートパラメータが行と列のサイズを定義する数独パズルのテンプレートクラスを書いています。C++11 を有効にして g++-4.8 を使用しています。
回避したコンパイルの問題が 1 つありますが、期待どおりに動作しない理由を理解したいと思います。
私の RowIteratorImpl クラスは VirtualLineIteratorImpl から派生していますが、そのフィールド virtualLineIdx および cellInVirtualLineIdx にアクセスできません。
class VirtualLineIteratorImpl : public CellIteratorImpl
{
protected:
size_t virtualLineIdx;
size_t cellInVirtualLineIdx;
public:
VirtualLineIteratorImpl(size_t virtualLineIdx)
: virtualLineIdx(virtualLineIdx), cellInVirtualLineIdx(0)
{}
virtual void increment(size_t offset)
{
virtualLineIdx += offset;
}
};
class RowIteratorImpl : public VirtualLineIteratorImpl
{
public:
using VirtualLineIteratorImpl::VirtualLineIteratorImpl;
virtual size_t getCellIdx() const
{
// TODO: does not compile
// return mivTSudoku::getCellIdxInRow(virtualLineIdx, cellInVirtualLineIdx);
return mivTSudoku::getCellIdxInRow(VirtualLineIteratorImpl::virtualLineIdx, VirtualLineIteratorImpl::cellInVirtualLineIdx);
}
};
コンパイラは次のメッセージを生成します。
mivSudoku.h: メンバー関数 'virtual size_t mivTSudoku::RowIteratorImpl::getCellIdx() const': mivSudoku.h:85:39: エラー: 'virtualLineIdx' はこのスコープで宣言されていませんでした リターン mivTSudoku::getCellIdxInRow(virtualLineIdx, cellInVirtualLineIdx );
これはクラス定義全体です。
#ifndef MIVSUDOKU_H
#define MIVSUDOKU_H
#include <bitset>
#include <iterator>
#include <memory>
template<size_t n, size_t m=n>
class mivTSudoku
{
public:
class Cell
{};
static constexpr size_t getCellIdx(size_t rowIdx, size_t colIdx)
{
return rowIdx * dim + colIdx;
}
static constexpr size_t getCellIdxInRow(size_t rowIdx, size_t cellInRowIdx)
{
return getCellIdx(rowIdx, cellInRowIdx);
}
static constexpr size_t getCellIdxInColumn(size_t columnIdx, size_t cellInColumnIdx)
{
return getCellIdx(cellInColumnIdx, columnIdx);
}
static constexpr size_t getCellIdxInBlock(size_t blockIdx, size_t cellInBlockIdx)
{
return getCellIdx((blockIdx / n) * n + (cellInBlockIdx / m), (blockIdx % n) * m + (cellInBlockIdx % m));
}
class CellIteratorImpl
{
public:
virtual CellIteratorImpl* clone() = 0;
virtual void increment(size_t) = 0;
virtual void getCellIdx() const = 0;
};
class AllCellIteratorImpl : public CellIteratorImpl
{
private:
size_t m_cellIdx;
public:
AllCellIteratorImpl()
: m_cellIdx(0)
{}
virtual void increment(size_t offset)
{
m_cellIdx += offset;
}
virtual void getCellIdx() const
{
return m_cellIdx;
}
};
class VirtualLineIteratorImpl : public CellIteratorImpl
{
protected:
size_t virtualLineIdx;
size_t cellInVirtualLineIdx;
public:
VirtualLineIteratorImpl(size_t virtualLineIdx)
: virtualLineIdx(virtualLineIdx), cellInVirtualLineIdx(0)
{}
virtual void increment(size_t offset)
{
virtualLineIdx += offset;
}
};
class RowIteratorImpl : public VirtualLineIteratorImpl
{
public:
using VirtualLineIteratorImpl::VirtualLineIteratorImpl;
virtual size_t getCellIdx() const
{
// TODO: does not compile
//return mivTSudoku::getCellIdxInRow(virtualLineIdx, cellInVirtualLineIdx);
return mivTSudoku::getCellIdxInRow(VirtualLineIteratorImpl::virtualLineIdx, VirtualLineIteratorImpl::cellInVirtualLineIdx);
}
};
typedef std::bidirectional_iterator_tag CellIterator_tag;
typedef std::iterator<CellIterator_tag, Cell> CellIteratorBase;
class Cellterator : public CellIteratorBase
{
private:
typedef CellIteratorBase baseclass;
protected:
mivTSudoku* pSudoku;
CellIteratorImpl* m_pIterImpl;
public:
Cellterator(mivTSudoku* pSudoku, CellIteratorImpl* impl) noexcept
: pSudoku(pSudoku), m_pIterImpl(impl)
{
}
~Cellterator()
{
delete m_pIterImpl;
m_pIterImpl = nullptr;
}
Cellterator(const Cellterator& rhs) noexcept
: pSudoku(pSudoku), m_pIterImpl(rhs.m_pIterImpl->clone())
{}
Cellterator(Cellterator&& rhs) noexcept
: pSudoku(pSudoku), m_pIterImpl(rhs.m_pIterImpl)
{
rhs.m_pIterImpl = nullptr;
}
Cellterator& operator=(const Cellterator& rhs) noexcept
{
if (this == &rhs) return *this;
this->pSudoku = rhs.pSudoku;
this->m_pIterImpl = rhs.m_pIterImpl->clone();
}
Cellterator& operator=(Cellterator&& rhs) noexcept
{
if (this == &rhs) return *this;
this->pSudoku = rhs.pSudoku;
this->m_pIterImpl = rhs.m_pIterImpl;
rhs.m_pIterImpl = 0;
}
size_t getCellIdx() const
{
return m_pIterImpl->getCellIdx();
}
typedef typename baseclass::reference reference;
reference operator*()
{
return pSudoku->m_field[getCellIdx()];
}
reference const operator*() const
{
return pSudoku->m_field[getCellIdx()];
}
typedef typename baseclass::pointer pointer;
pointer operator->()
{
return pSudoku->m_field + getCellIdx();
}
pointer const operator->() const
{
return pSudoku->m_field + getCellIdx();
}
Cellterator& operator++()
{
m_pIterImpl->increment(1);
return *this;
}
Cellterator operator++(int)
{
Cellterator iter;
this->operator++();
return iter;
}
bool operator==(const Cellterator& rhs) const
{
return getCellIdx()==rhs.getCellIdx();
}
bool operator!=(const Cellterator& rhs) const
{
return !operator==(rhs);
}
};
public:
static const size_t dim = n*m;
static const size_t ncells = dim*dim;
private:
Cell m_field[dim];
};
typedef mivTSudoku<3,3> mivSudoku;
#endif // MIVSUDOKU_H
なぜ私に説明できますか?