Reputation: 77941
I guess that there should be someway to write the below piece of code without using "for" loops and by just using STL algorithms and iterators. If I am not wrong can anyone guide me on how to do this?
std::vector<double> A(N);
std::vector<double> B(N);
std::vector<double> C(N);
std::vector<double> D(N);
for(int i = 0; i < N; ++i)
A[i] = myFunction1(i);
for(int i = 0; i < N; ++i)
B[i] = myFunction2(A[i], i);
for(int i = 0; i < N; ++i)
C[i] = myFunction3(A[i], B[i]);
for(int i = 0; i < N; ++i)
D[i] = myFunction4(A[i], B[i], i);
Upvotes: 4
Views: 888
Reputation: 279245
typedef boost::counting_iterator<int> counter;
std::transform(counter(0), counter(N), A.begin(), myFunction1);
std::transform(A.begin(), A.end(), counter(0), B.begin(), myFunction2);
std::transform(A.begin(), A.end(), B.begin(), C.begin(), myFunction3);
Now write your own version of std::transform
that takes a ternary function:
template <typename In1, typename In2, typename In3, typename Out, typename FUNC>
Out transform3(In1 first1, In1 last1, In2 first2, In3 first3, Out out, FUNC f) {
while (first1 != last1) {
*out++ = f(*first1++, *first2++, *first3++);
}
return out;
}
transform3(A.begin(), A.end(), B.begin(), counter(0), D.begin(), myFunction4);
I guess there might be something you can do with variadic templates in C++0x to get a transform_N
, but if so I don't know what it is, I've never used them. Not sure if you can forward a variable number of arguments with modifications (in this case wrapping * ++
around each one, as it were).
Upvotes: 4
Reputation: 283634
Example using std::transform
#include <algorithm>
#include <vector>
double myFunction1(int) { return 0; }
double myFunction2(double, int) { return 1; }
double myFunction3(double, double) { return 2; }
double myFunction4(double, double, int) { return 3; }
struct int_sequence
{
int_sequence(int i) : val(i) {}
int_sequence operator++() { ++val; return *this; }
int_sequence operator++(int) { return int_sequence(val++); }
int operator*() const { return val; }
bool operator!=(const int_sequence& other) const { return val != other.val; }
private:
int val;
};
const size_t N = 100;
int main(void)
{
std::vector<double> A(N);
std::vector<double> B(N);
std::vector<double> C(N);
std::vector<double> D(N);
//for(int i = 0; i < N; ++i)
// A[i] = myFunction1(i);
std::transform(int_sequence(0), int_sequence(N), A.begin(), &myFunction1);
//for(int i = 0; i < N; ++i)
// B[i] = myFunction2(A[i], i);
std::transform(A.begin(), A.end(), int_sequence(0), B.begin(), &myFunction2);
//for(int i = 0; i < N; ++i)
// C[i] = myFunction3(A[i], B[i]);
std::transform(A.begin(), A.end(), B.begin(), C.begin(), &myFunction3);
for(int i = 0; i < N; ++i)
D[i] = myFunction4(A[i], B[i], i);
// there is no std::transform for three-argument functions (yet)
return 0;
}
Upvotes: -1
Reputation: 45493
You will need a bit of BOOST to do this all with functional work (or else make your own versions of boost::counting_iterator)
//for(int i = 0; i < N; ++i)
// A[i] = myFunction1(i);
std::transform(
boost::counting_iterator<int>(0),
boost::counting_iterator<int>(N),
A.begin(),
&myFunction1);
//for(int i = 0; i < N; ++i)
// B[i] = myFunction2(A[i], i);
std::transform(
A.begin(),
A.end(),
boost::counting_iterator<int>(0),
B.begin(),
&myFunction2);
//for(int i = 0; i < N; ++i)
// C[i] = myFunction3(A[i], B[i]);
std::transform(
A.begin(),
A.end(),
B.begin(),
C.begin(),
&myFunction3);
// The STL doesn't have a version of transform that takes three inputs, but given a transform_3 that does:
//for(int i = 0; i < N; ++i)
// D[i] = myFunction4(A[i], B[i], i);
transform_3(
A.begin(),
A.end(),
B.begin(),
boost::counting_iterator<int>(0),
D.begin(),
&myFunction4);
That transform_3
function might look something like this:
// Untested code
template <class input1, class input2, class input3, class output, class oper>
output transform_3 (input1 in1begin, input1 in1end, input2 in2, input3 in3, output out, oper op)
{
while (in1begin != in1end)
*(out++) = op(*(in1begin++), *(in2++), *(in3++));
return out;
}
Upvotes: 3
Reputation: 190935
Why not combine the 4 loops into 1?
for(int i = 0; i < N; ++i) {
A[i] = myFunction1(i);
B[i] = myFunction2(A[i], i);
C[i] = myFunction3(A[i], B[i]);
D[i] = myFunction4(A[i], B[i], i);
}
Upvotes: 1