I want to implement partial specializations for different container iterators. The code compiles fine if I do that for containers as such, but fails for their iterators:
Good
template<typename T>
struct IsContainer : std::false_type {};
template<typename T>
struct IsContainer<std::list<T>> : std::true_type {};
template<typename T>
struct IsContainer<std::set<T>> : std::true_type {};
template<typename T1, typename T2>
struct IsContainer<std::map<T1, T2>> : std::true_type {};
Produces error:
Class template partial specialization contains a template parameter that cannot be deduced; this partial specialization will never be used
for each specialization:
template<typename T>
struct IsIterator : std::false_type {};
template<typename T>
struct IsIterator<std::list<T>::iterator> : std::true_type {};
template<typename T>
struct IsIterator<std::set<T>::iterator> : std::true_type {};
template<typename T1, typename T2>
struct IsIterator<std::map<T1, T2>::iterator> : std::true_type {};
What is the correct form for iterators?
The compiler message is quite descriptive here. That is the way how compiler deals with template specializations. I'll try to explain why this would be impossible to implement from the compiler's point of view.
When you have the following code:
template<typename T>
struct IsContainer : std::false_type {};
template<typename T>
struct IsContainer<std::list<T>> : std::true_type {};
when compiler needs to instantiate IsContainer<SomeType>
it needs to check whether SomeType
is a std::list
with some template arguments or not, and this is quite doable. If yes - it uses partial specialization, if not - the generic one.
Let's try do the same for the following code:
template<typename T>
struct IsIterator : std::false_type {};
template<typename T>
struct IsIterator<typename std::list<T>::iterator> : std::true_type {};
If compiler needs to instantiate IsContainer<SomeType>
it would need to check if SomeType
is std::list<T>::iterator
for some type T. Since list<T>::iterator
is some independent type (theoretically) from list<T>
the only option to do it is to enumerate all the possible types (including infinite number of template instantiations), which is obviously impossible.
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