Search code examples
templatesc++11vectoriteratorshared-ptr

Vector Iterators of Shared Pointers


I'm trying to get an iterator to my vector of shared_ptr. Its giving me 2 compile errors:

syntax error : missing ';' before identifier 'begin'
missing type specifier - int assumed. Note: C++ does not support default-int

In the code, if I replace the vector's entry type with string or something basic, it compiles. [of course thats not what I want]. Whats going on?

#include <vector>
#include <unordered_map>
#include <memory>

template<class _Kty, class _Ty> class MyClass {
public:
    typedef std::shared_ptr<std::pair<_Kty, _Ty>> Entry;

    // Vector containing pairs of the key & value
    std::vector<Entry> container;

    // Beginning iterator to the vector part
    std::vector<Entry>::iterator begin() noexcept {
        return containervector.begin();
    }
};

Solution

  • std::vector<Entry>::iterator is a dependent name.

    Use typename as a hint for the compiler regarding that nested ::iterator something:

       typename std::vector<Entry>::iterator begin() noexcept {
    // ^^^^^^^^
    

    Q & A section:

    Why typedef std::string Entry; works without typename ?

    std::string is an explicit instantiation of a template std::basic_string<char>, hence, the compiler knows everything about this type and its nested member classes.

    Why did I need a typename for the shared_ptr version of code?

    This is because what is hidden behind std::vector<Entry> depends on the arguments supplied to the template. That is, the std::vector<Entry>::iterator will vary depending on what the Entry is, and the Entry itself utilizes template parameters (because it has std::pair<_Kty, _Ty>), and the iterator member may not exist at all, or it may be e.g. a static object instead of a type. typename is a hint for the compiler.