容器迭代器的部分专业化失败

时间:2019-04-09 09:26:53

标签: c++

我想为不同的容器迭代器实现部分专业化。如果我对容器这样的话,代码可以很好地编译,但是对于它们的迭代器来说则失败:

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 {};

迭代器的正确形式是什么?

1 个答案:

答案 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}}唯一的选择就是枚举所有可能的类型(包括无限数量的模板实例化),这显然是不可能的。

相关问题