たとえば、次の 2 つの関数があるとします。
void合計(int x, int y) { x+y を返します。 } void マイナス (int x, int y) { xy を返します。 }
個別の関数を明示的に記述することなく、使用するものに応じて (おそらく何らかのキーワードによって) 合計またはマイナス (またはその他のさまざまなこと) を行う単一の関数を作成する方法はありますか?
たとえば、次の 2 つの関数があるとします。
void合計(int x, int y) { x+y を返します。 } void マイナス (int x, int y) { xy を返します。 }
個別の関数を明示的に記述することなく、使用するものに応じて (おそらく何らかのキーワードによって) 合計またはマイナス (またはその他のさまざまなこと) を行う単一の関数を作成する方法はありますか?
質問の下のコメントで、ある種の私をこれに打ち負かしましたが、どうぞ!
#include <functional>
#include <iostream>
#include <unordered_map>
std::unordered_map<std::string, std::function<int(int,int)>> operations =
{
{ "plus", std::plus<int>() },
{ "minus", std::minus<int>() }
// etc etc
};
int main(int argc, char** argv)
{
std::cout << operations["plus"](1, 2) << std::endl;
std::cout << operations["minus"](2, 1) << std::endl;
}
この関数は、実際にはあなたが投稿したものよりも少し頑丈であると思います(これは、関数から値を返すことをコンパイルしませんvoid
)。関数オブジェクトを使用して、動作をカスタマイズできます。たとえば、次のようになります。
#include <functional>
#include <iostream>
using namespace std::placeholders;
template <typename Op>
int operation(int a0, int a1, Op op = Op())
{
return op(a0, a1);
}
int my_f0(int a0, int a2)
{
return 2 * a0 + 3 * a2;
}
int my_f2(int a0, int a2, int f0, int f1)
{
return f0 * a0 + f1 * a2;
}
int main()
{
std::cout << operation<std::plus<int> >(2, 3) << "\n";
std::cout << operation<std::minus<int> >(2, 3) << "\n";
std::cout << operation(2, 3, std::multiplies<int>()) << "\n";
std::cout << operation(2, 3, my_f0) << "\n";
std::cout << operation(2, 3, std::bind(&my_f2, _1, _2, 2, 3)) << "\n";
}
カスタマイズ機能はoperation()
. 他のコードは、カスタマイズ方法を示すためのものです。標準ライブラリのアルゴリズムは、いたるところでこのアプローチを使用しています。
マクロが地獄からの悪であると信じていない場合は、次のようにすることができます。
#define DEFINE_OPERATION(maName, maOp) \
inline int maName (int a, int b) { return a maOp b; }
DEFINE_OPERATION(add, +)
DEFINE_OPERATION(sub, -)
#undef DEFINE_OPERATION
あるいは:
#include <boost/preprocessor.hpp>
#define OPERATIONS ((add, +))((sub, -))
#define DEFINE_OPERATION(maR, maData, maElem) \
inline int BOOST_PP_TUPLE_ELEM(2, 0, maElem) (int a, int b) { return a BOOST_PP_TUPLE_ELEM(2, 1, maEleme) b; }
BOOST_PP_SEQ_FOR_EACH(OPERATIONS, unused_, DEFINE_OPERATION)
#undef DEFINE_OPERATION