【发布时间】:2017-01-26 22:55:16
【问题描述】:
假设我们有以下情况:
struct A
{
int i;
};
struct B
{
A a;
int other_things;
};
bool predicate( const A& a)
{
return a.i > 123;
}
bool predicate( const B& b)
{
return predicate(b.a);
}
int main()
{
std::vector< A > a_source;
std::vector< B > b_source;
std::vector< A > a_target;
std::vector< B > b_target;
std::copy_if(a_source.begin(), a_source.end(), std::back_inserter( a_target ), predicate);
std::copy_if(b_source.begin(), b_source.end(), std::back_inserter( b_target ), predicate);
return 0;
}
对std::copy_if 的调用都会产生编译错误,因为predicate() 函数的正确重载无法由编译器推断,因为std::copy_if 模板签名接受任何类型的谓词:
template<typename _IIter,
typename _OIter,
typename _Predicate>
_OIter copy_if( // etc...
如果我将 std::copy_if 调用包装到一个更受约束的模板函数中,我发现重载解决方案有效:
template<typename _IIter,
typename _OIter,
typename _Predicate = bool( const typename std::iterator_traits<_IIter>::value_type& ) >
void copy_if( _IIter source_begin,
_IIter source_end,
_OIter target,
_Predicate pred)
{
std::copy_if( source_begin, source_end, target, pred );
}
我的问题是:为什么在 STL 中它还没有受到这样的约束?从我所见,如果_Predicate 类型不是返回bool 并接受迭代输入类型的函数,那么无论如何它都会生成编译器错误。那么为什么不把这个约束放在签名中,以便重载解析可以工作呢?
【问题讨论】:
-
您的约束太强(
const不需要,允许进行一些转换(int到bool))。decltype将允许正确的要求(或概念),但该方法是在 c++11 之前完成的。
标签: c++ c++11 stl stl-algorithm