前向迭代器的重载
Overloading for forward iterators
在研究 libc++ 时,我发现当模板参数是前向迭代器时,有两种不同的函数重载方法。
第一种方法是使用 std::iterator_traits::iterator_category
template <class ForwardIter1, class ForwardIter2>
inline
bool
__some_function(ForwardIter1 first1, ForwardIter1 last1,
ForwardIter2 first2, ForwardIter2 last2,
std::forward_iterator_tag, std::forward_iterator_tag)
{
// do stuff ...
return true;
}
template <class InputIter1, class InputIter2>
inline
bool
__some_function(InputIter1 first1, InputIter1 last1,
InputIter2 first2, InputIter2 last2,
std::input_iterator_tag, std::input_iterator_tag)
{
// do stuff ...
return true;
}
template <class InputIter1, class InputIter2>
inline
bool
some_function(InputIter1 first1, InputIter1 last1,
InputIter2 first2, InputIter2 last2)
{
return __some_function(first1, last1, first2, last2,
typename std::iterator_traits<InputIter1>::iterator_category(),
typename std::iterator_traits<InputIter2>::iterator_category());
}
但我也看到了 std::enable_if
的用法
template <class ForwardIter1, class ForwardIter2>
inline
bool
some_function(ForwardIter1 first1, ForwardIter1 last1,
ForwardIter2 first2, ForwardIter2 last2,
typename std::enable_if<
__is_forward_iterator<ForwardIter1>::value &&
__is_forward_iterator<ForwardIter2>::value
>::type* = 0)
{
// do stuff ...
return true;
}
template <class InputIter1, class InputIter2>
inline
bool
some_function(InputIter1 first1, InputIter1 last1,
InputIter2 first2, InputIter2 last2,
typename std::enable_if<
__is_exactly_input_iterator<InputIter1>::value &&
__is_exactly_input_iterator<InputIter2>::value
>::type* = 0)
{
// do stuff ...
return true;
}
这两个中哪一个是 "prefered" 解决问题的方法,还是要视情况而定。在那种情况下,什么时候一种解决方案会比另一种更好?
更好的方法是将 enable if
用作 return 类型,这样就无需将任何额外参数(具有默认值)传递给函数:
template <class ForwardIter1, class ForwardIter2>
typename std::enable_if
<
__is_forward_iterator<ForwardIter1>::value
&&
__is_forward_iterator<ForwardIter2>::value
, bool
>::type
some_function
(
ForwardIter1 first1, ForwardIter1 last1
, ForwardIter2 first2, ForwardIter2 last2
)
{
// do stuff ...
return(true);
}
也保留带有双下划线的标识符,但我们假设 __is_forward_iterator
模板有效并且存在于某处。
在研究 libc++ 时,我发现当模板参数是前向迭代器时,有两种不同的函数重载方法。
第一种方法是使用 std::iterator_traits::iterator_category
template <class ForwardIter1, class ForwardIter2>
inline
bool
__some_function(ForwardIter1 first1, ForwardIter1 last1,
ForwardIter2 first2, ForwardIter2 last2,
std::forward_iterator_tag, std::forward_iterator_tag)
{
// do stuff ...
return true;
}
template <class InputIter1, class InputIter2>
inline
bool
__some_function(InputIter1 first1, InputIter1 last1,
InputIter2 first2, InputIter2 last2,
std::input_iterator_tag, std::input_iterator_tag)
{
// do stuff ...
return true;
}
template <class InputIter1, class InputIter2>
inline
bool
some_function(InputIter1 first1, InputIter1 last1,
InputIter2 first2, InputIter2 last2)
{
return __some_function(first1, last1, first2, last2,
typename std::iterator_traits<InputIter1>::iterator_category(),
typename std::iterator_traits<InputIter2>::iterator_category());
}
但我也看到了 std::enable_if
template <class ForwardIter1, class ForwardIter2>
inline
bool
some_function(ForwardIter1 first1, ForwardIter1 last1,
ForwardIter2 first2, ForwardIter2 last2,
typename std::enable_if<
__is_forward_iterator<ForwardIter1>::value &&
__is_forward_iterator<ForwardIter2>::value
>::type* = 0)
{
// do stuff ...
return true;
}
template <class InputIter1, class InputIter2>
inline
bool
some_function(InputIter1 first1, InputIter1 last1,
InputIter2 first2, InputIter2 last2,
typename std::enable_if<
__is_exactly_input_iterator<InputIter1>::value &&
__is_exactly_input_iterator<InputIter2>::value
>::type* = 0)
{
// do stuff ...
return true;
}
这两个中哪一个是 "prefered" 解决问题的方法,还是要视情况而定。在那种情况下,什么时候一种解决方案会比另一种更好?
更好的方法是将 enable if
用作 return 类型,这样就无需将任何额外参数(具有默认值)传递给函数:
template <class ForwardIter1, class ForwardIter2>
typename std::enable_if
<
__is_forward_iterator<ForwardIter1>::value
&&
__is_forward_iterator<ForwardIter2>::value
, bool
>::type
some_function
(
ForwardIter1 first1, ForwardIter1 last1
, ForwardIter2 first2, ForwardIter2 last2
)
{
// do stuff ...
return(true);
}
也保留带有双下划线的标识符,但我们假设 __is_forward_iterator
模板有效并且存在于某处。