template<class T>
struct is_iterator
{
static const bool value = ??? // What to write ???
};
int main()
{
assert(false == is_iterator<int>::value);
assert(true == is_iterator<vector<int>::iterator>::value);
assert(true == is_iterator<list<int>::iterator>::value);
assert(true == is_iterator<string::iterator>::value);
assert(true == is_iterator<char*>::value); // a raw pointer is also an iterator
}
Run Code Online (Sandbox Code Playgroud)
问题是:如何使五个断言语句通过?
许多容器类模板都有一个构造函数,它接受一个计数和一个样本元素作为参数,另一个构造函数接受一对输入迭代器。其他方法如insert表现出相同的模式。当模板使用整数类型实例化时,一个幼稚的实现会遇到麻烦,并且构造函数(或其他方法)使用一对整数调用:它们的类型相等,输入迭代器方法将给出有效的参数类型推导,但随后无法编译。
我正在寻找一种优雅的方式来指定输入迭代器方法只参与重载实际上是有效输入迭代器类型的(相等)参数类型,或者至少不参与整数类型。我的印象是 SFINAE 是要走的路(但很高兴被告知不同的方式),但是在阅读它时,坦率地说我不太了解规则,而且示例中提供的解决方案几乎不符合优雅.
作为附带限制,我希望我的代码能够与不完整的 C++11 支持的 gcc 4.6 兼容。值得注意的是,我想避免使用模板别名。这是我笨拙的尝试(裸露的骨头):
#include <iterator>
#include <type_traits>
#include <vector>
template <typename I>
struct input_iter : public std::integral_constant<bool,
not std::is_integral<I>::value
and std::is_base_of
<std::input_iterator_tag
,typename std::iterator_traits<I>::iterator_category
>::value >
{};
template<typename T>
struct container
{
container (size_t count, const T& init);
template <typename InputIt,
typename = typename std::enable_if<input_iter<InputIt>::value>::type >
container (InputIt first,InputIt last);
};
typedef container<int> int_cont;
void f()
{ std::vector<int> v (5,3);
int_cont a1 (3u,6); // first constructor
int_cont a2 (3u,6); // first …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 {};
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)
迭代器的正确形式是什么?