Reputation: 1610
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();
}
};
Upvotes: 1
Views: 155
Reputation: 48447
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 withouttypename
?
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 theshared_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.
Upvotes: 2