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"));
}
それはいいですか?