开发者

Template class nested in template class giving errors in MSVC++

I'm getting errors I can't understand in MSVC++ 2008 express edition. First, I'll show a stripped version of my code (necessary includes ignored):

template <class Key,class Value>
class BinaryTree
{
public:
 typedef std::pair<Key&,Value&> Element;

...

protected:
 template <bool _Reverse>
 class Iterator : public std::iterator<std::bidirectional_iterator_tag,Element>
 {
 public:
  Iterator(const Iterator<_Reverse>& other);

  Iterator& operator++();

 ...

 protected:
  typedef BinaryTree<Key,Value> Parent;

  Iterator(Parent* parent,bool isEnd = false);
 }
}

...

//Definition bodies (in the same file)

...

template <class Key,class Value,bool _Reverse> //line 118
inline BinaryTree<Key,Value>::Iterator<_Reverse>::Iterator(Parent* parent,bool isEnd = false)
 //has an initialisation list (removing it didn't make a difference to the errors)
{
 ...
} //line 126

...

template <class Key,class Value,bool _Reverse>
inline BinaryTree<Key,Value>::Iterator<_Reverse>::Iterator(const Iterator<_Reverse>& other)
 : _stack(other._stack), _parent(other._parent), _null(other._null)
{
} //line 132

...

//the next two are specialisations
template <class Key,class Value>
typename BinaryTree<Key,Value>::Iterator<false>& BinaryTree<Key,Value>::Iterator<false>::operator++()
{
 ...
} //line 196


template <class Key,class Value>
typename BinaryTree<Key,Value>::Iterator<true>& BinaryTree<Key,Value>::Iterator<false>::operator++()
{
 ...
} //line 211

And the errors I get are:

//normal constructor
binarytree.h(126) : error C3860: template argument list following class template name must list parameters in the order used in template parameter list
binarytree.h(126) : error C3855: 'BinaryTree<Key,Value>::Iterator<_Reverse>': template parameter '_Reverse' is incompatible with the declaration
binarytree.h(126) : error C2977: 'BinaryTree<Key,Value>::Iterator<_Reverse>' : too many template arguments
binarytree.h(118) : error C2952: 'BinaryTree<Key,Value>::Iterator<_Reverse>::Iterator' : template declaration missing template parameter list

//copy constructor
binarytree.h(132) : error C2244: 'BinaryTree<Key,Value>::Iterator<_Reverse>::{ctor}' : unable to match function definition to an existing declaration
        definition
        'BinaryTree<Key,Value>::Iterator<_Reverse>::Iterator(const BinaryTree<Key,Value>::Iterator<_Reverse> &)'
        existing declarations
        'BinaryTree<Key,Value>::Iterator<_Reverse>::Iterator(BinaryTree<Key,Value> *,bool)'
        'BinaryTree<Key,Value>::Iterator<_Reverse>::Iterator(const BinaryTree<Key,Value>::Iterator<_Reverse> &)'        //isn't this one clearly identical?

//operator++ - template specialisations
binarytree.h(196) : error C2244: 'BinaryTree<Key,Value>::Iterator<_Reverse>::operator ++' : unable to match function definition to an existing declaration
        definition
        'BinaryTree<Key,Value>::?$Iterator@$0A@ &BinaryTree<Key,Value>::Iterator<false>::operator ++(void)'
        existing declarations
        'BinaryTree<Key,Value>::Iterator<_Reverse> BinaryTree<Key,Value>::Iterator<_Reverse>::operator ++(int)'
        'BinaryTree<Key,Value>::Iterator<_Reverse> &BinaryTree<Key,Value>::Iterator<_Reverse>::operator ++(void)'

binarytree.h(211) : error C2244: 'BinaryTree<Key,Value>::Iterator<_Reverse>::operator ++' : unable to match function definition to an existing declaration
        definition
        'BinaryTree<Key,Value>::?$Iterator@$00 &BinaryTree<Key,Value>::Iterator<true>::operator ++(void)'
        existing declarations
        'BinaryTree<Key,Value>::Iterator<_Reverse> BinaryTree<Key,Value>::Iterator<_Reverse>::operator ++(int)'
        'BinaryTree<Key,Value>::Iterator<_Reverse> &BinaryTree<Key,Value>::Iterator<_Reverse>::operator ++(void)'

As far as I can tell, every single member function has one of these three error groups.

I could potentially solve all of these problems by removing the templated paramater of Iterator, making a second class ReverseIterator which derives and overrides the necessary functions. But I'd prefer to fix it this way, to help me understand what's going wrong.

EDIT: Could somebody fix the code tags? Doesn't seem to be working like I'd expect.

EDIT2: Okay, the second template instruction worked flawlessly. However it seems that the template specialisation errors are occurring because you aren't allowed to specialise an inner class if you don't specialise the outer class. I can work around this, but it means I'm relying on the compiler optimising out certain things. For example, instead of writing:

template <class Key,class Value>
inline bool BinaryTree<Key,Value>::Iterator<false>::DoStuff()
{
    return FalseCode();
}

template <class Key,class Value>
inline bool BinaryTree<Key,Value>::Iterator<true>::DoStuff()
{
    return TrueCode();
}

I've used:

template <class Key,class Value>
template <bool Reverse>
inline bool BinaryTree<Key,Value>::Iterator<Reverse>::DoStuff()
{
   开发者_C百科 if(Reverse) //hopefully is optimised out; at compile time is either true or false
    {
        return TrueCode();
    }
    return FalseCode();
}

I can't help but think that more complex situations might result in the compiler not omitting an unecessary branch. I guess that depends on the compiler however.


Since these are two independent template classes, it should be for example like this:

template <class Key,class Value>
template <bool _Reverse>
inline BinaryTree<Key,Value>::Iterator<_Reverse>::Iterator(const Iterator<_Reverse>& other)
 : _stack(other._stack), _parent(other._parent), _null(other._null)
{
} //line 132

but take a note that a variables starting with the underscore are usually reserved for the compiler's implementation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜