Чтобы узнать версию машинописного текста, установленную на моем компьютере, используйте эту команду в командной строке.
tsc - версия
Суммирование STL может быть выполнено с помощью std :: accumulate
#include <functional>
accumulate(v.begin(), v.end(), 0, bind(plus<int>(), _1, bind(&ABCD::a, _2)))
. Если вы хотите, чтобы это было более универсальным, вы можете взять tr1 :: function для члена, который хотите привязать :
int sum_over_vec(const vector<ABCD>& v, const tr1::function<int (const ABCD&)>& member)
{
return accumulate(v.begin(), v.end(),
0,
bind(plus<int>(),
_1,
bind(member, _2)));
};
// ...
int sum_a = sum_over_vec(vec, bind(&ABCD::a, _1));
Другой способ сделать это, вместо того, чтобы помещать вашу логику в функтор, - это поместить логику в итератор, используя итератор boost :: transform:
tr1::function<int (const ABCD&)> member(bind(&ABCD::a, _1));
accumulate(make_transform_iterator(v.begin(), member),
make_transform_iterator(v.end(), member),
0);
EDITED TO ADD: синтаксис лямбда-выражения C ++ 11
Это становится несколько яснее с лямбдами C ++ 11 (хотя, к сожалению, не короче):
accumulate(v.begin(), v.end(), 0,
[](int sum, const ABCD& curr) { return sum + curr.a });
и
int sum_over_vec(const vector<ABCD>& v, const std::function<int (const ABCD&)>& member)
{
return accumulate(v.begin(), v.end(), 0,
[&](int sum, const ABCD& curr) { return sum + member(curr}); });
};
Использование:
// Use a conversion from member function ptr to std::function.
int sum_a = sum_over_vec(vec, &ABCD::a);
// Or using a custom lambda sum the squares.
int sum_a_squared = sum_over_vec(vec,
[](const ABCD& curr) { return curr.a * curr.a; });
Другой вариант - использовать указатель на члены:
int CalcSumOf(const VecABCD & vec, int ABCD::*member)
{
int sum = 0;
for(VecABCD::const_iterator it = vec.begin(), end = vec.end(); it != end; ++it)
sum += (*it).*member;
return sum;
}
...
int sumA = CalcSumOf(myVec, &ABCD::a); // find sum of .a members
int sumB = CalcSumOf(myVec, &ABCD::b); // find sum of .b members
// etc.
Вы можете использовать for_each . Это вариант.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef struct{
int a;
}ABCD;
typedef vector<ABCD> vecABCD;
struct sum : public unary_function<ABCD, void>
{
sum(){count.a=count.b=count.c=count.d=0;}
void operator() (ABCD x) {
count.a+=x.a;
count.b+=x.b;
count.c+=x.c;
count.d+=x.d;
}
ABCD count;
};
int main()
{
ABCD s1={1,2,3,4};
ABCD s2={5,6,7,8};
vecABCD v;
v.push_back(s1);
v.push_back(s2);
sum s = for_each(v.begin(), v.end(), sum());
cout<<s.count.a<<endl;
}
вывод:
4
Добавим еще один вариант, к сожалению, некрасивый. Можно взять относительный адрес от начала структуры ABCD до ее члена с помощью функции offsetof. Доставьте возвращаемое значение функции, и она может производить подсчет с использованием относительного местоположения от начала каждой структуры. Если ваши типы могут отличаться от int, вы можете также предоставить информацию о размере.