C++ C+中的foreach算法+;

C++ C+中的foreach算法+;,c++,C++,有没有一种方法可以让我传递给foreach的函数返回值 例如: 我有 void myfunction(int i) { 不能。但是你可以把myfunction变成一个函子,给它传递一个指向某个内存的指针,并通过该指针存储你的返回值 struct MyFunctor { int *count; MyFunctor(int *count_) : count(count_) { } void operator()(int n) { if (n > 5) (

有没有一种方法可以让我传递给foreach的函数返回值

例如: 我有

void myfunction(int i)
{

不能。但是你可以把
myfunction
变成一个函子,给它传递一个指向某个内存的指针,并通过该指针存储你的返回值

struct MyFunctor {
    int *count;
    MyFunctor(int *count_) : count(count_) { }
    void operator()(int n) {
        if (n > 5) (*count)++;
    }
};

int main() {
    vector<int> vec;
    for (int i=0; i<10; i++) vec.push_back(i);
    int count = 0;
    for_each(vec.begin(), vec.end(), Myfunctor(&count));
    printf("%d\n", count);
    return 0;
}
struct MyFunctor{
整数*计数;
MyFunctor(int*count_u1;):count(count_1;){
void运算符()(int n){
如果(n>5)(*计数)+;
}
};
int main(){
向量向量机;

对于(int i=0;i这不是它的用途吗?

有一个特殊的
std::count
(计算值的出现次数)和
std::count\u if
(当谓词返回true时计数)为此,请不要滥用
std::for_each
,因为它不适用于任何用途。

for_each
将返回您传递的函子副本。这意味着您可以执行以下操作:

template <typename T>
class has_value
{
    has_value(const T& pValue) : mValue(pValue), mFlag(false) {}

    void operator()(const T& pX)
    {
        if (pX == mValue)
            mFlag = true;
    }

    operator bool(void) const { return mFlag; }
private:
    T mValue;
    bool mFlag;
};

bool has_seven = std::for_each(myvector.begin(), myvector.end(), has_value<int>(7));
模板
类有其自身的价值
{
has_值(const T&pValue):mValue(pValue),mFlag(false){
void运算符()(常量T和pX)
{
if(pX==mValue)
mFlag=真;
}
运算符bool(void)const{return mFlag;}
私人:
T值;
bool-mFlag;
};
bool has_seven=std::for_each(myvector.begin()、myvector.end()、has_值(7));
例如。但是对于计数等,请检查并查看您的函数是否已经存在。(例如)

请查看


我想这就是你要找的。

std::for_每个
都不是为此而设计的。使用
std::count
来计算等于某个值的元素数,或者使用
std::count_如果
来计算满足某个谓词的元素数:

std::vector<SomeType> vec;
std::count(vec.begin(), vec.end(), SomeType(9));
/*or */
bool myfunc(const SomeType& v)
{
    return v == 9;
}
std::count_if(vec.begin(), vec.end(), f);
如果需要函数每次调用的返回值,请使用
std::transform

std::vector<SomeType> src;
std::vector<SomeType> result;
int myfunc(int val)
{
    ...
}
std::transform(src.begin(), src.end() \
    result.begin(), myfunc);
std::vector src;
std::向量结果;
int myfunc(int val)
{
...
}
std::transform(src.begin(),src.end())\
result.begin(),myfunc);
std::transform
也被重载,因此它适用于二进制函数和一元函数。

它是可行的:

int main()
{
  std::vector<int> v;
  for (int i = 1; i <= 10; i++)
    v.push_back(i);

  int hits = 0;
  CountEven evens(&hits);
  std::for_each(v.begin(), v.end(), evens);
  std::cout << "hits = " << hits << std::endl;

  return 0;
}
请注意,复制构造函数会导致多个实例共享同一指针


使用或。

如果您想要强大的foreach,则有BOOST\u foreach makro。此外,BOOST主要是标题库,因此您只能在项目中包含BOOST\u foreach.hpp(afair)。例如:

BOOST_FOREACH( int & i , my_vector )
{
     i = 0;
}

我的向量可以是
vector
int[]
或任何其他类型的迭代器。

好吧,我担心你在遇到计数问题时选择的示例不正确

问题是每个
都非常通用,并且针对特定的实现存在更具体的算法(
计数
累积
转换
,…)

因此,让我们再举一个例子:
for_each
通常用于对其处理的对象应用变异操作。这并不妨碍您在进行此操作时收集统计信息

我们必须小心,虽然每个
都会返回一个
谓词
对象,但不能保证该对象被用于范围内的每个项目。实现可以自由复制谓词,并在范围的一部分使用副本…因此,您最终返回的副本可能无法使用

class Predicate
{
public:
  Predicate(size_t& errors) : m_errors(errors) {}
  void operator()(MyObject& o)
  {
    try { /* complicated */ } catch(unfit&) { ++m_errors; }
  }
private:
  size_t& m_errors;
};

std::vector<MyObject> myVec;
// fill myVec

size_t errors = 0;
std::for_each(myVec.begin(), myVec.end(), Predicate(errors));
类谓词
{
公众:
谓词(size_t&errors):m_errors(errors){}
void运算符()(MyObject&o)
{
尝试{/*复杂*/}捕获(不适合&){++m_错误;}
}
私人:
尺寸、测试和维护错误;
};
std::载体myVec;
//填充myVec
尺寸误差=0;
std::for_each(myVec.begin()、myVec.end()、谓词(errors));

这里的诀窍是,原始谓词的所有副本都将指向相同的
size\t
变量,因此此变量已正确更新。

您可以调整
std::for\u each
,如GMan所示

但更好的解决方案是使用正确的算法

您应该能够使用
std::count
std::count\u(如果
),或者
std::accumulate
。 这些允许您为处理整个序列返回一个结果


或者,
std::transform
允许您为序列中的每个元素返回一个结果,创建一个包含结果的新输出序列。

当您的答案出现时,我正在编写同一代码的一半,很高兴看到我不是唯一一个直接进行此操作的人。+1对于漂亮的演员技巧,我想我还有很多事情要做关于函数这是不可移植的,但是不能保证在将传递的副本应用到输入范围之前,
for_each
不会复制返回值的输入函数,或者不会制作多个副本并将不同的副本应用到范围的每个成员。标准规定“将f应用于从第一个到最后一个-1的范围[first,last]中的每个迭代器的解引用结果。返回:f。”SGI网站还说,“For_每个在应用于每个元素后返回函数对象。"我认为任何返回预应用副本的实现都是不符合标准的,对吗?返回值的全部目的是获取应用的函子。这根本不起作用。因为该实现可以随意复制谓词,所以您可能最终得到一个在其生命周期内从未见过单个
7
的副本e、 …这不应该起作用。functor被复制到每个
,并且该副本是有意义的副本。你应该为每个
使用
的返回值。实际的替代方法是让
MyFunctor
保存对外部对象的引用,这样所有副本都共享相同的引用,因此指向的对象被启动日期正确。和-1,因为一开始就不是正确的算法。他问了一个更一般的问题,然后给出了一个更具体的用例。回答mor有错吗
class CountEven {
  public:
  CountEven(int *hits) : hits(hits) {}
  CountEven(const CountEven &rhs) : hits(rhs.hits) {}
  void operator() (int n) { if (n % 2 == 0) ++*hits; }

  private:
  int *hits;
};
BOOST_FOREACH( int & i , my_vector )
{
     i = 0;
}
class Predicate
{
public:
  Predicate(size_t& errors) : m_errors(errors) {}
  void operator()(MyObject& o)
  {
    try { /* complicated */ } catch(unfit&) { ++m_errors; }
  }
private:
  size_t& m_errors;
};

std::vector<MyObject> myVec;
// fill myVec

size_t errors = 0;
std::for_each(myVec.begin(), myVec.end(), Predicate(errors));