0

https://gist.github.com/2934374

したがって、私はこの比較と、コメントに表示されたひどい C++ ソリューションに興味をそそられましたが、自分で良いソリューションを書くのに苦労していることを認めなければなりません :-)

私の現在の試みは次のようになります。問題は次のとおりです。

  • ツリーの作成時に環境がコピーされるため、ツリーの作成後に変数を変更できるようにしたい
  • それはまだかなり醜く見える

では、どうすればそれを少しつぶして変数をバインドし、変更の影響を受けるようにできますか?

#include <map>
#include <string>
#include <iostream>
#include <functional>
using namespace std;

/* environ */
map<string,int> variables = { { "a" , 3 }, { "b", 4 }, { "c", 5 } };

function<int(int,int)> add = [] (int lp, int rp) { return lp + rp; };
function<int(int,int)> mlt = [] (int lp, int rp) { return lp * rp; };

/* impl */
struct Var {
    Var(int v) : p_v(v) {};
    int eval() { return p_v; };

private:
    int p_v;
};

template <typename LP, typename RP>
struct Op {
    Op(function<int(int,int)> op, LP lp, RP rp) : p_op(op), p_l(lp), p_r(rp) {};
    int eval() { return p_op(p_l.eval(), p_r.eval()); }
private:
    function<int(int,int)> p_op;
    LP p_l;
    RP p_r;
};

Var var(int val) { return Var(val); }

template <typename LP, typename RP>
auto op(function<int(int,int)> op, LP lp, RP rp) -> Op<LP,RP>
{
    return Op<LP,RP>(op,lp,rp);
}

Var operator "" _var(const char *key, size_t length)
{ return Var(variables[key]); }

/* gcc is failing me
Var operator "" _num(int val)
{ return Var(val); }
*/

int main()
{
    auto tree = op ( add, "a"_var, op ( mlt, var ( 2 ), "b"_var ));
    cout << tree.eval() << endl;
}
4

1 に答える 1

3

あなたは標準のバインドメカニズムを再発明しています。ユーザーがグルーコードを作成する必要はありません。

auto tree = bind(plus<int>(), ref(variables["a"]), bind(multiplies<int>(), 2, ref(variables["b"])));
cout << tree();

http://liveworkspace.org/code/f06fd83b5d7bcbf4829306d4e590da38

std::ref値ではなく参照になります。これは、変更操作をバインドできることを意味します。

于 2012-09-05T16:22:36.827 に答える