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