gpt4 book ai didi

c++ - 为什么 std::copy_if 签名不约束谓词类型

转载 作者:可可西里 更新时间:2023-11-01 15:06:20 25 4
gpt4 key购买 nike

假设我们有以下情况:

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 并接受迭代输入类型的函数,它无论如何都会生成编译器错误。那么为什么不把这个约束已经放在签名中,这样重载解析就可以工作了?

最佳答案

因为谓词不一定是函数,也可以是仿函数。限制仿函数类型几乎是不可能的,因为它可以是任何东西,只要它定义了 operator()

实际上,我建议您在这里将重载函数转换为多态仿函数:

struct predicate {
bool operator()( const A& a) const
{
return a.i > 123;
}

bool operator()( const B& b) const
{
return operator()(b.a);
}
}

并用实例调用仿函数,即

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());
// ^^ here, see the ()

然后将在算法内部选择正确的重载。

关于c++ - 为什么 std::copy_if 签名不约束谓词类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39569982/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com