1

I'm writing a template class which should behave like a container. Inner data is a vector of smart pointers to the generic class T.

Header

#include <vector>
#include <boost/shared_ptr.hpp>

namespace Foo
{
  template <class T>
  class AstrContainer
  {

  public:

      typedef boost::shared_ptr<T> p_element;
      typedef std::vector<p_element> v_p_elements;

  protected:

    v_p_elements _vData;

  public:
    AstrContainer();
    virtual ~AstrContainer();

    typename v_p_elements::iterator begin();
    typename v_p_elements::iterator end();
  };
}

Source

#include "AstrContainer.hpp"

namespace Foo
{
    template<class T>
    AstrContainer<T>::AstrContainer()
    {
    }

    template<class T>
    AstrContainer<T>::~AstrContainer()
    {
    }

    typename
    v_p_elements::iterator AstrContainer<T>::begin() // - - - ERROR LINE 1 - - -
    {
        return _vData.begin();
    }

    template<class T>
    typename v_p_elements::iterator AstrContainer<T>::end() // - - - ERROR LINE 2 - - -
    {
        return _vData.end();
    }
}

I'm very new to template classes in C++, and got a bit stucked at the ERROR LINE 1

error C2653: 'v_p_elements': is not a class or namespace name

So I commented the begin() method, but at ERROR LINE 2 it halts with the same error.

Now it seems clear that, since v_p_elements is being typedef'd inside the class, that maybe it cannot be exported to the outer world. But now I'm asking if the whole thing is even possible, or if I'm just misunderstanding something.

Patrizio Bertoni
  • 2,582
  • 31
  • 43
  • 1
    You will probably also soon run into this problem: [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file?noredirect=1&lq=1) – Bo Persson Aug 05 '16 at 10:17

2 Answers2

1

You could add qualified enclosing class name.

template<class T>
typename AstrContainer<T>::v_p_elements::iterator AstrContainer<T>::end()
//       ~~~~~~~~~~~~~~~~~~
{
    return _vData.end();
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • Great, but if I inherit in `class CompositeCube : public AstrContainer`, I got in a third class, which calls `CompositeCube cc; cc.begin();`, the following: *LNK2019 unresolved external symbol* – Patrizio Bertoni Aug 05 '16 at 12:26
  • 1
    @PatrizioBertoni Did you separate the declaration and implementation of class template into header file and implementation file (just as you showed)? See the comment of Bo Persson. – songyuanyao Aug 05 '16 at 13:10
  • Thank you, answer from MaHuJa solved everything smoothly ! – Patrizio Bertoni Aug 05 '16 at 13:37
1

An alternative is to use the trailing return type:

template<class T>
auto AstrContainer<T>::end() -> typename v_p_elements::iterator
{
    return _vData.end();
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302