在C ++中,我正在实现vector
类,并在使用任何类型作为T
的参数时遇到错误:
void insert(iterator where, size_type count, const_reference value = T()){...}
template <typename InIt>
void insert(iterator where, InIt first, InIt last){...}
执行以下操作时:
vector<int> v;
for (int i = 0; i < 5; ++i)
{
v.push_back(i + 1);
}
v.insert(v.begin() + 2, 10, 8);
v.insert(v.begin() + 4, 9);
它将InIt
的参数作为int
,它实际上应该是iterator
类型类,并且意味着调用了错误的函数,导致内部内存错误。因此,我不得不使用insert
参数删除template <typename InIt>
函数,因为它会破坏我的实现。我用std::string
尝试过这个问题,同样的问题就出现了。
我能做些什么来区分这两个功能吗?
答案 0 :(得分:5)
这就是SFINAE的用途 - 如果InIt
不是看起来像迭代器的东西,则从重载集中删除第二个重载。在这种情况下,您只需要一个输入迭代器,它必须是可递增的和可解除引用的:
template <typename InIt,
typename = decltype(*std::declval<InIt&>(),
++std::declval<InIt&>())>
void insert(iterator where, InIt first, InIt last)
{
...
}
如果您使用某种整数类型调用insert
(以便可以将其转换为size_t
),*std::declval<InIt&>
将是无效的表达式,因为整数类型不可解除 - 所以模板扣除会失败。因为 S ubstitution F ailure 我 s N ot A n E rror,效果是这个重载被从考虑中移除,而第一个将被调用。
答案 1 :(得分:1)
从Concepts Iterator引用中您有几个选项,以检查特定类型的迭代器:
(see)