有没有办法确保在C ++中传递的模板参数是一个迭代器?

时间:2015-06-29 18:50:30

标签: c++ templates

在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尝试过这个问题,同样的问题就出现了。

我能做些什么来区分这两个功能吗?

2 个答案:

答案 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引用中您有几个选项,以检查特定类型的迭代器

  

C++ Conceptssee