2

我有一个元素容器,每个元素都有它的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

我想要做到这一点,而不是仅仅为 size 成员函数定义二进制操作add_size,而是使用 mem_fun 和 binders。我怎样才能做到这一点?我怎样才能有效地做到这一点?我一开始add_element就卡住了。

我需要在 C++03 中工作的解决方案。

4

1 回答 1

2

I believe your question is ill-posed. Look at what you have: a small one-liner function add_size and a call to std::accumulate. What's not to like?

You are somehow (for perhaps corporate reasons) restricted from using either Boost.Bind or Boost.Lambda, let alone C++11 (which standardized both std::bind and lambda expressions).

You want to eliminate that in favor of the C++03 binders which are horribly limited in their expressiveness (which is BTW one reason why Boost.Bind and Boost.Lambda were so popular) and would require much more boilerplate than what you currently have. Look at this appendix of the C++ Standard Reference book by Nicolai Jusuttis. He implements a general compose template that works "nicely" with std::bind2nd and friends. But look at which headers he uses to implement that: right, the Boost.Bind ones.

Your best approach is to simply copy Boost.Bind and/or Boost.Lambda, put them in your own source tree, and rename the namespace to your company's. Check whether this is in fact consistent with the Boost License. Boost even has a bcp tool to extract all the included dependencies for you. Then simply write whatever you need to using the bind or lambda facilities that you've just "written".

TL;DR: Do not Re-invent the Wheel. Familiarize yourself with Boost.

于 2013-05-08T12:58:53.153 回答