C++ 特定类型的迭代器-函数参数-元编程

C++ 特定类型的迭代器-函数参数-元编程,c++,iterator,C++,Iterator,我正在尝试编写一个函数,它接受给定类型的(正向)迭代器。使用SFINAE将非常有帮助。我提出了以下(无效)解决方案: template<class ForwardIterator, typename std::enable_if< std::is_same<typename std::iterator_traits<ForwardIterator>::value_type, int>::value >::type >

我正在尝试编写一个函数,它接受给定类型的(正向)迭代器。使用SFINAE将非常有帮助。我提出了以下(无效)解决方案:

template<class ForwardIterator,
    typename std::enable_if<
        std::is_same<typename std::iterator_traits<ForwardIterator>::value_type, int>::value
    >::type
>
    inline void foo(ForwardIterator begin, ForwardIterator end)
{
}
template::type
>
内联void foo(ForwardIterator开始,ForwardIterator结束)
{
}
在这种情况下,foo应该可以通过
std::vector::iterator
调用,或者只通过提供原始int指针来调用。问题是,它没有像我预期的那样工作。编译器(msvc 2019)总是抱怨没有找到匹配的重载函数


该代码有什么问题?

这不起作用的原因是,如果
enable\u if
得到一个真值,您的声明将解析为

template<class ForwardIterator, void>
然而,这带来了另一个问题。模板参数的默认值不是其签名的一部分。因此,如果我们尝试添加一个重载,将
int
替换为
double
,我们将得到一个错误,因为两个模板函数具有相同的签名

为了解决第二个问题,我们将第二个参数改为非类型参数。这将使签名彼此唯一

template<class ForwardIterator,
typename std::enable_if<
    std::is_same<typename std::iterator_traits<ForwardIterator>::value_type, int>::value
>::type* = nullptr>
template::type*=nullptr>
现在,如果
enable\u if
成功,我们将得到一个
void*
非类型参数,默认值为
nullptr
,如果愿意,我们可以在
enable\u中添加具有不同要求的重载

SFINAE通常用于根据条件在不同的函数之间进行选择,如果您只想限制模板
static\u assert
很可能是更好的选择


更易于编写,更易于阅读,并且在编译失败时会收到更具描述性的错误消息。

您缺少
std::enable_if::type
参数的默认值。您这样做只是为了避免用户使用错误的迭代器/对象调用
foo
,或者您需要SFINAE在多个
foo
s之间进行选择吗?我只是想避免用户使用错误的参数调用foo。@在这种情况下,使用
static\u assert
的NeconPictor可能更容易获得相同的结果。
std::enable\u if::type
的默认值是
void
。应该没关系吧?谢谢你的解释!我之所以喜欢SFINAE,是因为如果您使用了错误的输入,IDE会立即将其标记为错误。但是我明白了其中的要点,为什么
static\u assert
是更好的选择。所以我会用它来代替。不过,我学到了更多关于C++的知识:
template<class ForwardIterator,
typename std::enable_if<
    std::is_same<typename std::iterator_traits<ForwardIterator>::value_type, int>::value
>::type* = nullptr>