У меня есть контейнер элементов, и каждый элемент имеет свой size()
функция-член. Мне удалось накопить общий размер элементов контейнера, написав бинарную операцию add_size
:
#include <algorithm>
#include <vector>
#include <functional>
#include <numeric>
#include <iostream>
class A
{
int size_ ;
public:
A ()
:
size_(0)
{}
A (int size)
:
size_(size)
{}
int size() const
{
return size_;
}
};
template<typename Type>
class add_element
{
Type t_;
public:
add_element(Type const & t)
:
t_(t)
{}
void operator()(Type & t)
{
t += t_;
}
};
int add_size (int i, const A& a)
{
return i+=a.size();
}
using namespace std;
int main(int argc, const char *argv[])
{
typedef vector<A> Vector;
Vector v;
v.push_back(A(10));
v.push_back(A(5));
v.push_back(A(7));
v.push_back(A(21));
v.push_back(A(2));
v.push_back(A(1));
int totalSize = accumulate(v.begin(), v.end(), 0, add_size);
std::cout << totalSize << endl;
return 0;
}
Это дает правильный вывод:
46
И то, что я хотел бы сделать это без определения бинарной операции add_size
только для функции-члена size, но с использованием mem_fun и binders. Как я могу это сделать? Как мне это сделать фактически? Я начал с add_element
и застрял.
Мне нужно решение для работы в C ++ 03.
Я считаю, что ваш вопрос некорректный. Посмотрите, что у вас есть: небольшая однострочная функция add_size
и вызов std::accumulate
, Что не нравится?
Вы каким-то образом (возможно, по корпоративным причинам) ограничены в использовании Boost.Bind или Boost.Lambda, не говоря уже о C ++ 11 (который стандартизировал оба std::bind
и лямбда-выражения).
Вы хотите устранить это в пользу связывателей C ++ 03, которые ужасно ограничены в их выразительности (что, кстати, одна из причин, почему Boost.Bind и Boost.Lambda были так популярны) и потребует гораздо большего количества шаблонов, чем то, что у вас есть в настоящее время. Посмотри на это приложение из C ++ Standard Справочник Николая Юсуттиса. Он реализует общее compose
шаблон, который работает «красиво» с std::bind2nd
и друзья. Но посмотрите, какие заголовки он использует для реализации этого: верно, Boost.Bind.
Ваш лучший подход — просто скопируйте Boost.Bind и / или Boost.Lambda, поместите их в свое собственное дерево исходных текстов и переименуйте пространство имен в свою компанию. Проверьте, действительно ли это соответствует Повышенная лицензия. Boost даже имеет bcp
инструмент для извлечения всех включенных зависимостей для вас. Затем просто напишите все, что вам нужно, используя средства bind или lambda, которые вы только что «написали».
TL; DR: Не переизобретай Колесо. Ознакомьтесь с Boost.
Других решений пока нет …