0

我没有使用 C++11 或 Boost。我想使用函子并传递给 std::for_each 等算法,但我认为必须在函数之外定义函子太麻烦了。我想在使用它们之前在函数中本地定义它们。但是,以下不起作用。这是由于旧的 C++ 标准不允许将本地定义的类用作模板参数(在 C++11 中修复)。

int main()
{
    std::vector<int> v(10);

    class SetInc
    {
    public:
        SetInc() : x(0) {}

        virtual void operator () (int& a)
        {
            a = x++;
        }

    private:
        int x;
    } f;

    std::for_each(v.begin(), v.end(), f);

    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, "\n"));
}

但我已经开发了以下解决方法:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>

template <typename ARGUEMENT, typename RESULT>
class FunctorBase
{
public:
    typedef ARGUEMENT argument_type;
    typedef RESULT result_type;

    virtual result_type operator () (argument_type) = 0;
    FunctorBase() {}
    virtual ~FunctorBase() {}
};

template <typename ARGUEMENT, typename RESULT>
class FunctorWrapper
{
public:
    typedef ARGUEMENT argument_type;
    typedef RESULT result_type;
    typedef FunctorBase<argument_type, result_type> Functor_T;

    explicit FunctorWrapper(Functor_T *functor)
        : functor(functor)
    {}

    result_type operator () (argument_type a)
    {
        return (*functor)(a);
    }

private:
    Functor_T *functor;
};

template <typename ARGUEMENT, typename RESULT>
FunctorWrapper<ARGUEMENT, RESULT> make_unary_functor(FunctorBase<ARGUEMENT, RESULT>& f)
{
    return FunctorWrapper<ARGUEMENT, RESULT>(&f);
}

int main()
{
    std::vector<int> v(10);

    class SetInc : public FunctorBase<int&, void>
    {
    public:
        SetInc() : x(0) {}

        virtual result_type operator () (argument_type a)
        {
            a = x++;
        }

    private:
        int x;
    } f;

    std::for_each(v.begin(), v.end(), make_unary_functor(f));

    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, "\n"));
}

这样好吗?

4

3 回答 3

2

问题是,在 C++ 98 中没有外部绑定的类型不能是模板参数。所以你能做的最好的就是把你的 SetInc 放到一个未命名的命名空间中。

我不知道您的解决方法是否以可移植的方式解决了问题,但它更难理解(您确实需要评论您的解决方法,以确保人们理解您为什么这样做)。编译器要优化虚函数调用要困难得多。

于 2013-03-21T17:23:24.437 回答
1

一个明显的问题是虚函数调用。使用普通函数对象,可以内联被调用的函数;带有虚函数,可能不是。所以你最终会为小功能带来更多的开销。

于 2013-03-21T17:27:30.370 回答
0

你不应该定义虚函数——没有多态性。你所有的代码都很好,但 STL 更好=)

看这里

http://www.cplusplus.com/reference/functional/binary_function/

http://www.cplusplus.com/reference/functional/unary_function/

在示例部分

struct IsOdd : public std::unary_function<int,bool> {
  bool operator() (int number) {return (number%2==1);}
};

PS:如果你想使用包装器而不是复制函子,这样重写它

模板

class FunctorWrapper
{
public:
    typedef F::argument_type argument_type;
    typedef F::result_type result_type;

explicit FunctorWrapper(F *functor)
    : functor(functor)
{}

result_type operator () (argument_type const & a) const
{
    return (*functor)(a);
}

result_type operator () (argument_type & a) const
{
    return (*functor)(a);
}

private:
    F *functor;
};

template <typename F>
FunctorWrapper<F> make_unary_functor(F& f)
{
    return FunctorWrapper<ARGUEMENT, RESULT>(&f);
}
于 2013-03-21T17:23:11.927 回答