I'd like to ask help with the correct syntax to declare a std::map whose mapped_type is an inner class of a template class.
Please find in the code below a #if/#else block. The "#if 1" block has template class Outer that contains inner class Inner. The Outer defines function Func that takes a std map whose mapped_type is of type Inner.
#include <map>
#if 1
template<typename C, typename T>
class Outer
{
public:
Outer(const C& c, const T& t){}
virtual ~Outer(){}
class Inner
{
public:
Inner(){}
Inner(T t){}
virtual ~Inner(){}
protected:
T mT;
};
void Func(std::map<C, Inner>& rMap);
protected:
std::map<C, Inner> mMap;
};
template<typename C, typename T>
void Outer<C, T>::Func(std::map<C, Outer::Inner>& rMap)
{
std::map<C, Inner>::iterator iter;
for (iter = rMap.begin(); iter != rMap.end(); ++iter)
{
mMap[iter->first] = iter->second;
}
}
#else
class Outer
{
public:
Outer(const int& i, const double& d){}
virtual ~Outer(){}
class Inner
{
public:
Inner() : mD(0){}
Inner(const double d) : mD(d){}
virtual ~Inner(){}
protected:
double mD;
};
void Func(std::map<int, Inner>& rMap);
protected:
std::map<int, Inner> mMap;
};
void Outer::Func(std::map<int, Inner>& rMap)
{
std::map<int, Inner>::iterator iter;
for (iter = rMap.begin(); iter != rMap.end(); ++iter)
{
mMap[iter->first] = iter->second;
}
}
#endif
int main()
{
return 0;
}
Compilation fails in Outer::Func(...) at the declaration of the std::map iterator, i.e. this line:
std::map<C, Inner>::iterator iter;
I've tried but cannot figure out what is wrong with the line of code.
For comparison/contrast, the "#else" block contains non-template code of similar nature. This code compiles.
The compile error and g++ version are:
>g++ main.cpp
main.cpp: In member function ‘void Outer<C, T>::Func(std::map<C, Outer<C, T>::Inner, std::less<_Key>, std::allocator<std::pair<const C, Outer<C, T>::Inner> > >&)’:
main.cpp:31: error: expected ‘;’ before ‘iter’
main.cpp:33: error: ‘iter’ was not declared in this scope
>g++ --version
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Thank you for any help.
Returns an iterator to the element with key-value 'g' in the map if found, else returns the iterator to end. crbegin() returns a constant reverse iterator referring to the last element in the map container.
It returns an iterator that yields the key-value pairs of the map. The initial value of this property is the same function object as the initial value of the Map.
For normal code, you would use a class template when you want to create a class that is parameterised by a type, and a function template when you want to create a function that can operate on many different types.
A C++ map is a way to store a key-value pair. A map can be declared as follows: #include <iostream> #include <map> map<int, int> sample_map; Each map entry consists of a pair: a key and a value.
Since Inner
is member of your template Owner<C, T>
, it becomes a dependent name. That causes the identifier iterator
, which in this case is a member of std::map<C, Inner>
, to become a dependent name aswell.
This forces you to use the keyword typename
, according to the rules:
typename std::map<C, Inner>::iterator iter;
~~~^~~~~
This is because the compiler can't be sure what certain constructs inside of your class mean since it does not know the exact types used for C
and T
yet:
Inside the definition of a template (both class template and function template), the meaning of some constructs may differ from one instantiation to another. In particular, types and expressions may depend on types of type template parameters and values of non-type template parameters.
The typename
keyword is used to tell the compiler that the symbol you are accessing is indeed a type alias / type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With