我想为不同的容器迭代器实现部分专业化。如果我对容器这样的话,代码可以很好地编译,但是对于它们的迭代器来说则失败:
好
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 {};
产生错误:
类模板的部分专业化包含无法推导的模板参数;这种部分专业化将永远不会使用
每个专业化
: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 {};
迭代器的正确形式是什么?
答案 0 :(得分:4)
此处的编译器消息具有很强的描述性。这就是编译器处理模板专业化的方式。我将尝试从编译器的角度解释为什么这不可能实现。
当您具有以下代码时:
template<typename T>
struct IsContainer : std::false_type {};
template<typename T>
struct IsContainer<std::list<T>> : std::true_type {};
当编译器需要实例化IsContainer<SomeType>
时,它需要检查SomeType
是否是带有模板参数的std::list
,这是完全可行的。如果是,则使用部分专业化;否则,则使用通用专业化。
让我们尝试对以下代码执行相同的操作:
template<typename T>
struct IsIterator : std::false_type {};
template<typename T>
struct IsIterator<typename std::list<T>::iterator> : std::true_type {};
如果编译器需要实例化IsContainer<SomeType>
,则需要检查某个类型T的SomeType
是否为std::list<T>::iterator
。由于list<T>::iterator
是(从理论上)与{ {1}}唯一的选择就是枚举所有可能的类型(包括无限数量的模板实例化),这显然是不可能的。