I am writing template class for a sudoku puzzle, where the template parameters define the size of the rows and columns. I am using g++-4.8 with C++11 enabled.
I have one compiling issue that I worked around, but I would like to understand why it is not working as expected:
My RowIteratorImpl class derives from VirtualLineIteratorImpl, but I cannot access its fields virtualLineIdx and cellInVirtualLineIdx although this should be possible:
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);
}
};
The compiler generates the following message:
mivSudoku.h: In member function ‘virtual size_t mivTSudoku::RowIteratorImpl::getCellIdx() const’:
mivSudoku.h:85:39: error: ‘virtualLineIdx’ was not declared in this scope
return mivTSudoku::getCellIdxInRow(virtualLineIdx, cellInVirtualLineIdx);
The issue is that names not depending on a template argument are looked up only when the template arguments are not known. Since your base class depends on a template argument (implicitly by being nested inside a template) the compiler diesn't look at the base class, yet: until the template is instantiated it could get specialuzed, resulting in a completely different class.
The fix is to make the reference to the base member depend on the template argument, e.g., by using this->virtualLineIdx.