डी

2011-10-19 34 views
19

में सुरुचिपूर्ण ऑपरेटर ओवरलोडिंग थोड़ी देर के लिए मैं डी ऑपरेटर ओवरलोडिंग की दिशा के बारे में उलझन में था, लेकिन अब मुझे एहसास है कि यह एक सुंदर प्रणाली है ... अगर यह केवल कोर प्रकारों (int, float, आदि) के साथ काम करेगी। अनुवर्ती कोड पर विचार करें: के रूप में यह सब overloadsडी

struct Vector { 
    float X, Y; 

    void opOpAssign(string op)(Vector vector) { 
     X.opOpAssign!op(vector.X); // ERROR: no property "opOpAssign" for float 
     Y.opOpAssign!op(vector.Y); // ERROR: ditto 
    } 
} 

इस खूबसूरत कोड अगर यह काम हो सकता है, देखकर + =, - =, * =, आदि .. एक विधि में ऑपरेटरों। हालांकि, जैसा कि आप देख सकते हैं, यह बॉक्स से बाहर काम नहीं करता है। मैं एक समाधान बनाया है का उपयोग कर टेम्पलेट्स (भगवान मैं डी प्यार):

template Op(string op, T) { 
    void Assign(ref T a, T b) { 
     static if (op == "+") a += b; 
      else if (op == "-") a -= b; 
      else if (op == "*") a *= b; 
      else if (op == "/") a /= b; 
    } 
} 

struct Vector { 
    float X, Y; 

    void opOpAssign(string op)(Vector vector) { 
     Op!(op, typeof(X)).Assign(X, vector.X); 
     Op!(op, typeof(Y)).Assign(Y, vector.Y); 
    } 
} 

यह केवल मैं चाहते ज्यादा "घर में" सब कुछ रखना पसंद करते हैं ठीक है। क्या इस काम को टेम्पलेट की सहायता के बिना बनाने का कोई तरीका है? मुझे पता है कि मैं यहाँ चुनौतीपूर्ण हूं, क्योंकि कोई प्रदर्शन हानि नहीं है और स्थिति में मॉड्यूल आयात करना मुश्किल नहीं है, मुझे ऐसा करने की ज़रूरत है। मैं बस सोच रहा हूं कि यह बनाया गया है और मैं कुछ दिख रहा हूं।

+0

ध्यान दें कि 'स्थिर if'' 'else' के बाद if's निम्नलिखित के लिए जारी रखा नहीं है:

क्या आप यहाँ करने के लिए कोशिश कर रहे हैं कि क्या करना है विहित रास्ता स्ट्रिंग mixins उपयोग करने के लिए है। आपको फिर से 'स्थैतिक' दोहराना होगा। – Bolpat

उत्तर

21

लगभग डी में सभी अतिभारित ऑपरेटरों परिभाषा द्वारा टेम्पलेट्स हैं जा सकते हैं। ध्यान दें कि void opOpAssign(string op)(Vector vector) में एक टेम्पलेट पैरामीटर है जो एक स्ट्रिंग है। इसलिए, नहीं, आप इसे गैर-टेम्पलेट फ़ंक्शन के रूप में अधिभारित नहीं कर सकते हैं। अब, आपको ऐसा करने के लिए दूसरे टेम्पलेट की आवश्यकता नहीं है (इसलिए यदि आप एक टेम्पलेट की आवश्यकता है या नहीं, तो आप एक सहायक टेम्पलेट का मतलब है, तो जवाब नहीं है), लेकिन ओवरलोडेड ऑपरेटर फ़ंक्शन पहले से ही एक टेम्पलेट है।

void opOpAssign(string op)(Vector vector) 
{ 
    mixin("X" ~ op ~ "=vector.X;"); 
    mixin("Y" ~ op ~ "=vector.Y;"); 
} 
+0

अरे तेज़ था! धन्यवाद! –

13
इस

void opOpAssign(string op)(Vector vector) { 
    mixin("X"~op~"=vector.X;"); 
    mixin("Y"~op~"=vector.Y;"); 
} 

को यह आसानी से अन्य अंकगणितीय आपरेशनों

Vector opBinary(string op)(Vector l)if(op=="+"||op=="-"){//only addition and subtraction makes sense for 2D vectors 
    mixin("return Vector(x"~op~"l.x,y"~op~"l.y;"); 
} 

///take in anything as long as a corresponding binaryOp exists 
///this essentially rewrites all "vec op= variable;" to "vec = vec op variable;" 
void opOpAssign(string op,T)(T l){ 
    this = this.binaryOp!op(l); 
} 

और यहां तक ​​कि दूसरे के लिए वेक्टर

Vector opBinary(string op)(real l)if(op=="*"||op=="/"){ 
    mixin("return Vector(x"~op~"l,y"~op~"l;"); 
} 

Vector opBinaryRight(string op)(real l)if(op=="*"){// for 2 * vec 
    return this*l; 
} 
स्केलिंग के लिए युग्मित किया जा सकता है का उल्लेख नहीं mixins के साथ जोड़ा जा करने के लिए है

ध्यान दें कि परिभाषित opBinary प्रतिबंधित है जो इसे पारित किया जा सकता है opOpAssign लेकिन आप दोनों तरीकों (opOpAssign के मामले में opBinary परिभाषित)

+0

जॉनथन ने पहले पोस्ट किया और अधिक समझाया, इसलिए मैंने उसे जवाब के रूप में चिह्नित किया, लेकिन मैं आपको इतनी जल्दी प्रतिक्रिया देने के लिए धन्यवाद देना चाहता हूं! –

+0

@FiL थोड़ी अधिक ओवरलोडिंग भलाई के लिए मेरे संपादन की जांच करें –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^