可以在函数体内局部定义函子吗?
我能想到的本地定义仿函数的一种可能用途(特别是如果我们想使用STL算法),可以说是
我们有两个向量std::vector<int>
的{{1}}和a
,然后我们可以在很多方面对它们进行相同的考虑。即b
,其中loop_counter不断变化,我们在每次循环迭代中测试它们是否相等。
a[i] = b[i] (mod loop_counter)
如果答案是否定的,那么如何进行上述操作,其中相等的条件随着每次迭代而不断变化?
注意:我尝试按如下方式定义一个仿函数(此处没有for(int i=0 ; i<=10 ; ++i)
{
//Define binary predicate functor my_local_predicate
//Test for equality using functor local to loop
std::equal(a.begin(), a.end(), b.begin, my_local_predicate)
// Do something if they are equal OR unequal
}
循环),但程序无法编译。
for
在#include <algorithm>
#include <iostream>
#include <list>
int main() {
class EvenOddFunctor
{
int even_;
int odd_;
public:
EvenOddFunctor() : even_(0), odd_(0) {}
void operator()(int x) {
if (x%2 == 0) even_ += x;
else odd_ += x;
}
int even_sum() const { return even_; }
int odd_sum() const { return odd_; }
};
EvenOddFunctor evenodd;
int my_list[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
evenodd = std::for_each(my_list,
my_list+sizeof(my_list)/sizeof(my_list[0]),
evenodd);
std::cout << "Sum of evens: " << evenodd.even_sum() << "\n";
std::cout << "Sum of odds: " << evenodd.odd_sum() << std::endl;
// output:
// Sum of evens: 30
// Sum of odds: 25
}
之前移动仿函数定义,干净地编译代码并正确执行。
因此,即使在函数体内定义一个仿函数似乎是不可能的,我想要一些好的STL就像在每次迭代中改变相等条件一样。
答案 0 :(得分:1)
如果你可以使用C ++ 11,那就行了。在C ++ 03中,您不能使用本地类作为模板参数。您可以使用std::accumulate
代替本地类静态函数(以及用于存储结果的非本地结构):
struct EvenOdd
{
int even;
int odd;
static EvenOdd empty() { EvenOdd result= { }; return result; }
};
int main()
{
struct EvenOddFunctor
{
static EvenOdd function(const EvenOdd &old_result, int x)
{
EvenOdd result= old_result;
if (x%2 == 0) result.even += x;
else result.odd += x;
return result;
}
};
EvenOdd evenOdd= std::accumulate(..., EvenOdd::empty(), EvenOddFunctor::function);
}
答案 1 :(得分:1)
(假设你被困在C ++ 03中。)
您可以让您的仿函数继承自顶级作用域中定义的模板基类,然后仅引用基类(例如,使用mem_fun / bind1st)。
template <typename T>
struct val_functor {
virtual ~val_functor() {}
virtual void operator()(T x) = 0;
};
int main()
{
class EvenOddFunctor : public val_functor<int>
...
std::for_each(my_list, my_list+sizeof(my_list)/sizeof(my_list[0]),
std::bind1st(
std::mem_fun(&val_functor<int>::operator()),
(val_functor<int>*)&evenodd)
);
...
}
答案 2 :(得分:0)
对于问题的第一部分,我不知道如何使用本地定义的函数。你需要的只是一种选择不同功能的方法,这很简单。例如:
std::function<bool(int,int)> my_functions[10];
my_functions[0] = std::equal_to<int>();
my_functions[1] = both_divisible_by_5;
...etc
for (int i=0; i<10; ++i)
{
if (std::equal(a.begin(), a.end(), b.begin, my_functions[i]))
{
...
}
}