1

I have:

struct A
{
    int index;

    A(): index(0) {}
}
std::vector<A> ManyAs(10, A());

And wants to do:

for (int i = 0, size = ManyAs.size(); i < size; ++i)
{
    ManyAs[i].index = i;
}

I want to do this with std algotrithm, maybe std::for_each?

How to do it, thanks!

3
  • 3
    I'd leave it like that - you need the loop counter, and the algorithms don't give you one. Commented Nov 29, 2013 at 12:36
  • They are vectors, instead of counting you could use pointer arithmetic to get i. Commented Nov 29, 2013 at 13:10
  • Why? This is fine the way it is. Commented Nov 29, 2013 at 13:21

4 Answers 4

3

I would do the following way

struct A
{
    int index;

    A(): index(0) {}
    A & operator =( int i )
    {
        index = i;
        return ( *this );
    }
};

std::iota( ManyAs.begin(), ManyAs.end(), 0 );
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for answering. But in my own opinion it's kind of non-intuitive...but still thanks!
Agreed. Now I have to go look at the definition to see what this is really doing. Complicating simple code isn't a good thing.
2

In this particular case, I'd leave the code as it is. Standard library algorithms are best used when you want to apply the same operation to all elements of the range. But here, you don't actually apply the same operation, as you assign a different number to each element's index. So a counter-based for loop seems to be the most natural solution here.

However, if you really want to use a standard algorithm, you can use a stateful functor:

struct Functor
{
  size_t index;
  Functor() : index(0) {}
  void operator() (A &a) { a.index = index++; }
};

std::for_each(ManyAs.begin(), ManyAs.end(), Functor());

1 Comment

Yes you're right, for_each is for the same operation, I got it. So maybe a generate or transform? Is there any more suitable algorithm? By the way, your functor is still a good point, thanks!
1

Here are two approaces:

struct my_functor
{
    my_functor()
        : i(0)
    {
    }
    void operator () (A & a)
    {
        a.index = i++;
    }
    int i;
};
void foo();
{
    //old c++ style
    std::for_each(ManyAs.begin(), ManyAs.end(), my_functor());
}

second:

//c++11
int i = 0;
std::for_each(ManyAs.begin(), ManyAs.end(), [&](A & a){ a.index = i++; });

2 Comments

You could define static int i = 0; inside the lambda itself.
@Nawaz yes, but i would not recommend that because i will never get set to 0 if the code that uses the lambda is reused.
0

Somehow I found my ideal answer:

std::for_each(ManyAs.begin(), ManyAs.end(),
    [&](A& a)
    {
        int offset=(&a) - (&ManyAs.front());
        a.index = offset;
    });

Actually it's quite similar to Raxvan's answer, but everything is local, which is better imo.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.