2012-01-22 15 views
0

我試圖寫一個解釋器將變成像一個字符串:更好的方式來綁定嵌套函數在我的翻譯

vector(random(0, 1), 2, 3)

成綁定功能使用boost::bind,如:

bind(&vector, bind(&random, 0, 1), 2, 3)

預期的用途是用於粒子系統,所以我希望能夠將粒子傳遞到這些粒子,這些粒子可以通過添加一個lambda來實現:

bind(&vector, bind(&random, 0, 1, _1), 2, 3, _1)

這些綁定函數然後定義爲: typedef boost::function<boost::any(Particle*)> bound_particle_func;,所以我可以形成一種的功能列表的調用每個粒子傳遞到該列表中操縱他們的行爲,從而創造的效果。

我可以很容易地做出解釋手柄類似vector(1, 2, 3)但是當涉及到嵌套函數事情越來越亂,我覺得我bodging事情。

因爲解析器當前以遞歸方式處理嵌套函數,所以我不能直接將lambda值綁定到嵌入函數。

,從而代替與 bind(&vector, bind(&random, 0, 1, _1), 2, 3, _1) 結束了我實際上 bind(&vector, bound random function, 2, 3, _1),其不通過所結合的功能的粒子結束。

我不知道如何更好地處理嵌套函數。

的實際代碼我有在時刻(這是不編譯的)是:

typedef std::vector<Token>::iterator token_it;  
typedef boost::function<boost::any(Particle*)> bound_particle_func; 
Vector3 vector(float x, float y, float z, Particle* p = 0); 
bound_particle_func parse(token_it& it); 

bound_particle_func ParseVector(std::vector<Token>& tokens) { 
     const static int arg_count = 3; 
     std::vector<boost::variant<float, bound_particle_func>> args(arg_count); 
     int type[] = { 0, 0, 0 }; 

     for(token_it it = tokens.begin(); it != tokens.end(); ++it) { 
       Token& t = *it; 

       if(t.type == Type::FLOAT) { 
         args.push_back(t.float_value); 
       } else if(t.type == Type::FUNCTION) { 
         args.push_back(parse(it)); 
         type[args.size() - 1] = 1; 
       } else { 
         throw std::runtime_error("Type error: expected float"); 
       } 

       if(args.size() > arg_count) { 
         throw std::runtime_error("Too many arguments for function `vector`"); 
       } 
     } 

     return boost::bind(&vector, (type[0] == 0 ? boost::get<float>(args[0]) : boost::get<bound_particle_func>(args[0])), 
            (type[1] == 0 ? boost::get<float>(args[1]) : boost::get<bound_particle_func>(args[1])), 
            (type[2] == 0 ? boost::get<float>(args[2]) : boost::get<bound_particle_func>(args[2])), 
            boost::lambda::_1); 
} 

bound_particle_func parse(token_it& it);功能只是傳遞相關令牌來像上面的一個適當的函數。

回答

0

請勿使用boost::functionboost::bind。您無法將boost::function傳遞給需要int的東西。

由於您只需要一種類型的延遲參數,並且需要將它傳遞給所有函數,所以更容易推出自己的函數對象。


,它使用boost::functionboost::bind是使用類似的東西替代:

Vector3 f_vector(bound_particle_func x, bound_particle_func y, 
        bound_particle_func z, Particle* p = 0) 
{ 
    return vector (boost::get<float>(x(p)), boost::get<float>(y(p)), 
        boost::get<float>(z(p)), p); 
} 

,同樣爲您的其他功能。數字由綁定函數表示,它們返回其綁定的參數float並忽略它們的參數Particle*

+0

我一直在使用函數對象,但在試圖通過不必爲每個函數編寫解析函數來添加新函數時遇到了問題,只是一個通用的函數對象,這就是爲什麼我轉向boost :: boost ::綁定'和'boost :: function' – Lerp