गतिशील भाव
आप उपयोगकर्ता से एक स्ट्रिंग प्राप्त करना चाहते हैं और उस से एक अभिव्यक्ति का निर्माण करते हैं, तो हो सकता है C++ Mathematical Expression Library अपने बिल फिट बैठता है?
template<typename T>
void trig_function()
{
std::string expression_string = "clamp(-1.0,sin(2 * pi * x) + cos(x/2 * pi),+1.0)";
T x;
exprtk::symbol_table<T> symbol_table;
symbol_table.add_variable("x",x);
symbol_table.add_constants();
exprtk::expression<T> expression;
expression.register_symbol_table(symbol_table);
exprtk::parser<T> parser;
parser.compile(expression_string,expression);
for (x = T(-5.0); x <= T(+5.0); x += 0.001)
{
T y = expression.value();
printf("%19.15f\t%19.15f\n",x,y);
}
}
भी संभावना है इस तरह के Lua या Python, जो आप (भी) और अधिक शक्ति दे देंगे के रूप में एक पटकथा भाषा एम्बेड करते हैं, कर रहे हैं। यह विचार करने के लिए कुछ है कि आप एक गेम लिख रहे हैं, क्योंकि आप शायद इसके बड़े हिस्सों को स्क्रिप्ट करना चाहते हैं।
आप Qt का उपयोग कर रहे हैं, तो आप भाव है कि पढ़ने के अपने QObject व्युत्पन्न वस्तुओं से (स्थिर या गतिशील) गुण को चलाने के लिए QtScript (जावास्क्रिप्ट-ish) का उपयोग कर सकते हैं।
उपर्युक्त में से किसी एक का उपयोग करके आप अपने स्वयं के पार्सर, एएसटी और मूल्यांकनकर्ता को लिखने से रोकते हैं, हालांकि ऑपरेटरों के एक छोटे से सेट के लिए यदि आप Boost.Spirit या कुछ अन्य सभ्य पार्सिंग का उपयोग करते हैं तो कुछ एक साथ हैक करना मुश्किल नहीं होना चाहिए पुस्तकालय।
स्टेटिक भाव
पूर्वनिर्धारित भाव का एक सेट के बीच चयन करने के लिए (अर्थात संकलन समय पर जाना जाता है), तो आप एक बहुरूपी समारोह वस्तु में अभिव्यक्ति की दुकान चाहिए।
सी ++ 11 के लिए, यदि यह आपके लिए उपलब्ध है, तो std::function
और लैम्ब्डा अभिव्यक्तियों का उपयोग करें।
std::function<bool (int, int)> expr = [](int a, int b) { a*2 < b };
पहले compilers के लिए, मैं समारोह और बाँध की सलाह देते हैं, या तो Boost (बढ़ावा में: :) या C++ 0x TR1 (एसटीडी: :), अपने संकलक पर निर्भर करता है। इसके अलावा, Boost.Lambda यहां सहायता की होगी, क्योंकि यह आपको बाद के मूल्यांकन के लिए अभिव्यक्तियों का निर्माण और संग्रह करने की अनुमति देता है। हालांकि, अगर आप सी ++ और टेम्पलेट्स (या कार्यात्मक प्रोग्रामिंग) से परिचित नहीं हैं, तो यह आपको काफी हद तक डराएगा।
इसी के साथ
आप
using namespace boost::lambda;
boost::function<bool (int, int)> myexpr1 = (_1 + _2) > 20;
boost::function<bool (int, int)> myexpr2 = (_1 * _2) > 42;
std::cout << myexpr1(4,7) << " " << myexpr2(2,5);
बाँध के साथ
लिख सकता है, यह देखने के लिए चाहते हैं की तरह:
boost::function<bool (Player&)> check = bind(&Player::getHealth, _1) > 20;
Player p1;
if (check(p1)) { dostuff(); }
check = bind(&Player::getGold, _1) < 42;
if (check(p1)) { doOtherStuff(); }
दुर्भाग्य से, यह मनमाना भाव के लिए पूरी तरह से अव्यावहारिक है। जो मुझे लगता है वह पोस्टर वास्तव में चाहता है (उसके उदाहरण के बावजूद "val1 op val2")। –
क्या यह है? बूस्ट :: लैम्ब्डा का उपयोग करके आप अभिव्यक्ति के सभी प्रकार, और यहां तक कि कथन और सभी को जोड़ सकते हैं। आपका क्या अर्थ है? – Macke
अच्छी तरह से, के बाद से बढ़ावा lambdas संकलन समय पर निर्माण कर रहे हैं और सिर्फ फोन करने वाले के द्वारा प्रयोग किया। यदि उपयोगकर्ता उस ऑप संयोजन में प्रवेश करता है जिसे आपने जिम्मेदार नहीं ठहराया है तो आप क्या करेंगे। चूंकि गणित संचालन के संयोजनों की असीमित संख्या है ... निश्चित रूप से आप उन सभी के लिए स्थैतिक रूप से खाता नहीं बना सकते हैं। –