রিটার্ন টাইপ দ্বারা ফাংশন ওভারলোডিং?


252

কেন আরও মূলধারার স্ট্যাটিকালি টাইপ করা ভাষাগুলি ফাংশন / পদ্ধতিটি রিটার্নের ধরণের মাধ্যমে ওভারলোডিং সমর্থন করে না? আমি কিছু করতে পারে না। এটি প্যারামিটার ধরণের মাধ্যমে ওভারলোডকে সমর্থন করার চেয়ে কম দরকারী বা যুক্তিসঙ্গত বলে মনে হয় না। এটি এত জনপ্রিয় জনপ্রিয় কিভাবে?


উত্তর:


523

অন্যরা কি বলছে, রিটার্ন টাইপ দ্বারা ওভারলোডিং বিপক্ষে হয় সম্ভব এবং করা হয় কিছু আধুনিক ভাষা দ্বারা সম্পন্ন। স্বাভাবিক আপত্তিটি কোডের মতো

int func();
string func();
int main() { func(); }

কোনটি func()বলা হচ্ছে তা আপনি বলতে পারবেন না । এটি কয়েকটি উপায়ে সমাধান করা যেতে পারে:

  1. এমন পরিস্থিতিতে কোন ফাংশনটি ডাকা হবে তা নির্ধারণ করার জন্য একটি অনুমানযোগ্য পদ্ধতি রয়েছে।
  2. যখনই এ জাতীয় পরিস্থিতি দেখা দেয় এটি একটি সংকলন-সময় ত্রুটি। যাইহোক, একটি বাক্য গঠন যে দুর্বোধ্য, যেমন করতে প্রোগ্রামার পারবেন আছে int main() { (string)func(); }
  3. পার্শ্ব প্রতিক্রিয়া নেই। যদি আপনার কোনও পার্শ্ব প্রতিক্রিয়া না থাকে এবং আপনি কখনই কোনও ফাংশনের রিটার্ন মান ব্যবহার করেন না, তবে সংকলকটি প্রথম স্থানে ফাংশনটি কল করা কখনও এড়াতে পারে।

আমি নিয়মিত দুটি ভাষা ( আব ) রিটার্ন টাইপের মাধ্যমে ওভারলোড ব্যবহার করি: পার্ল এবং হাস্কেল । তারা কি করে তা আমাকে বর্ণনা করুন।

ইন পার্ল , তার মাঝে একটি মৌলিক পার্থক্য স্কালে এবং তালিকা প্রসঙ্গ (এবং অন্যদের, কিন্তু আমরা ভান করব দুই আছে)। পার্লের প্রতিটি অন্তর্নির্মিত ফাংশন যে প্রসঙ্গে বলা হয় তার উপর নির্ভর করে বিভিন্ন জিনিস করতে পারে । উদাহরণস্বরূপ, joinঅপারেটর তালিকা প্রসঙ্গে তালিকাবদ্ধ করে (জিনিসটি যুক্ত হওয়ার সাথে সাথে) scalarঅপারেটর যখন স্কেলারের প্রসঙ্গটি জোর করে, তাই তুলনা করুন:

print join " ", localtime(); # printed "58 11 2 14 0 109 3 13 0" for me right now
print scalar localtime(); # printed "Wed Jan 14 02:12:44 2009" for me right now.

পার্লের প্রতিটি অপারেটর স্কেলারের প্রসঙ্গে এবং তালিকার প্রসঙ্গে কিছু করে এবং চিত্রিত হিসাবে সেগুলি আলাদা হতে পারে। (এটি কেবল এলোমেলো অপারেটরগুলির মতো নয় localtimeyou @aআপনি যদি তালিকার প্রসঙ্গে কোনও অ্যারে ব্যবহার করেন তবে এটি অ্যারেটি ফেরত দেয়, যখন স্কেলারের প্রেক্ষাপটে এটি উপাদানগুলির সংখ্যা প্রদান করে So সুতরাং উদাহরণস্বরূপ print @aউপাদানগুলি print 0+@aমুদ্রণের সময় , আকারটি প্রিন্ট করে। ) তদ্ব্যতীত, প্রতিটি অপারেটর একটি প্রসঙ্গ জোর করতে পারে , উদাহরণস্বরূপ +সংযোজনকারী প্রসঙ্গে প্রযোজ্য বাহিনীকে বাধ্য করে। man perlfuncনথি প্রতিটি এন্ট্রি । উদাহরণস্বরূপ, এখানে প্রবেশের অংশটি এখানে glob EXPR:

তালিকার প্রসঙ্গে, EXPRস্ট্যান্ডার্ড ইউনিক্স শেলের মতো ফাইলের নামের বিস্তারের একটি (সম্ভবত শূন্য) তালিকা প্রদান করে /bin/csh। স্কেলারের প্রসঙ্গে, গ্লোব এ জাতীয় ফাইলের বিস্তারের মাধ্যমে পুনরাবৃত্তি করে, তালিকাটি শেষ হয়ে গেলে অপরিবর্তিত হয়।

এখন, তালিকা এবং স্কেলারের প্রসঙ্গে কিসের সম্পর্ক? ভাল, man perlfuncবলেছেন

নিম্নলিখিত গুরুত্বপূর্ণ নিয়মটি মনে রাখবেন: এমন কোনও নিয়ম নেই যা মাপকাঠির প্রসঙ্গে তার আচরণের সাথে তালিকার পরিপ্রেক্ষিতে কোনও অভিব্যক্তির আচরণের সাথে সম্পর্কিত বা বিপরীতভাবে tes এটি দুটি সম্পূর্ণ ভিন্ন জিনিস করতে পারে। প্রতিটি অপারেটর এবং ফাংশন স্থিতিশীল প্রসঙ্গে ফিরে আসার জন্য কোন ধরণের মানটি সবচেয়ে উপযুক্ত তা স্থির করে। কিছু অপারেটর তালিকার দৈর্ঘ্য ফিরিয়ে দেয় যা তালিকা প্রসঙ্গে ফিরে আসত। কিছু অপারেটর তালিকার প্রথম মানটি ফেরত দেয়। কিছু অপারেটর তালিকার শেষ মানটি ফেরত দেয়। কিছু অপারেটর সফল অপারেশনগুলির একটি গণনা ফিরিয়ে দেয়। সাধারণভাবে, আপনি যা চান তা তারা করেন, যদি না আপনি ধারাবাহিকতা চান।

সুতরাং এটি একটি একক ক্রিয়াকলাপ করার কোনও সাধারণ বিষয় নয় এবং তারপরে আপনি শেষে সাধারণ রূপান্তর করেন। আসলে, আমি localtimeসেই কারণটির জন্য উদাহরণটি বেছে নিয়েছি ।

এটি কেবল বিল্ট-ইনগুলিই নয় যেগুলির এই আচরণ রয়েছে। যে কোনও ব্যবহারকারী এই জাতীয় ফাংশনটি ব্যবহার করে সংজ্ঞায়িত করতে পারেন wantarrayযা আপনাকে তালিকা, স্কেলার এবং শূন্য প্রসঙ্গের মধ্যে পার্থক্য করতে দেয়। সুতরাং, উদাহরণস্বরূপ, যদি আপনি অকার্যকর প্রসঙ্গে ডাকা হয় তবে আপনি কিছুই করার সিদ্ধান্ত নিতে পারেন।

এখন, আপনি অভিযোগ করতে পারেন যে এটি রিটার্ন ভ্যালু দ্বারা সত্য ওভারলোডিং নয় কারণ আপনার কেবল একটি ফাংশন রয়েছে, যা বলা হয় সেই প্রসঙ্গে বলা হয় এবং সেই তথ্যটিতে কাজ করে। যাইহোক, এটি স্পষ্টতই সমতুল্য (এবং পার্ল কীভাবে আক্ষরিক অর্থে সাধারণ ওভারলোডিংকে অনুমতি দেয় না তার অনুরূপ, তবে একটি ফাংশন কেবল তার যুক্তিগুলি পরীক্ষা করতে পারে)। তদুপরি, এটি এই প্রতিক্রিয়ার শুরুতে উল্লিখিত দ্ব্যর্থক পরিস্থিতি সুন্দরভাবে সমাধান করে। পার্ল অভিযোগ করেন না যে এটি কোন পদ্ধতিটি কল করতে জানে না; এটা ঠিক এটি কল। এটিকে যা করতে হবে তা হ'ল ফাংশনটি কী প্রসঙ্গে ডাকা হয়েছিল, যা সর্বদা সম্ভব:

sub func {
    if( not defined wantarray ) {
        print "void\n";
    } elsif( wantarray ) {
        print "list\n";
    } else {
        print "scalar\n";
    }
}

func(); # prints "void"
() = func(); # prints "list"
0+func(); # prints "scalar"

(দ্রষ্টব্য: আমি কখনও কখনও পার্ল অপারেটর বলতে পারি যখন আমি ফাংশন বলতে চাইছি This এটি এই আলোচনার পক্ষে গুরুত্বপূর্ণ নয়))

পার্শ্ব প্রতিক্রিয়া না হওয়ার জন্য হাস্কেল অন্য পদ্ধতি অবলম্বন করে। এটিতে একটি শক্তিশালী টাইপ সিস্টেম রয়েছে এবং তাই আপনি নীচের মতো কোড লিখতে পারেন:

main = do n <- readLn
          print (sqrt n) -- note that this is aligned below the n, if you care to run this

এই কোডটি স্ট্যান্ডার্ড ইনপুট থেকে ভাসমান পয়েন্ট সংখ্যাটি পড়ে এবং এর বর্গমূলকে মুদ্রণ করে। তবে এতে অবাক হওয়ার কী আছে? ওয়েল, ধরণ readLnহয় readLn :: Read a => IO a। এর অর্থ কী তা হ'ল যে কোনও প্রকারের জন্য Read(আনুষ্ঠানিকভাবে, প্রতিটি ধরণের যা Readটাইপ শ্রেণীর একটি উদাহরণ ), readLnএটি পড়তে পারে। হাস্কেল কীভাবে জানল যে আমি একটি ভাসমান পয়েন্ট নম্বর পড়তে চাইছি? ওয়েল, ধরণ sqrtহয় sqrt :: Floating a => a -> a, যা মূলত মানে যে sqrtশুধুমাত্র ভাসমান ইনপুট হিসাবে পয়েন্ট সংখ্যা গ্রহণ করতে পারে, এবং তাই Haskell, অনুমিত আমি যা চেয়েছিলাম।

হাসেল যখন আমি যা চাই তা অনুমান করতে না পারলে কী ঘটে? ঠিক আছে, কয়েকটি সম্ভাবনা আছে। আমি যদি রিটার্ন মানটি ব্যবহার না করি তবে হাস্কেল কেবল প্রথম স্থানে ফাংশনটি কল করবে না। যাইহোক, যদি আমি না ফেরত মান ব্যবহার করেন, তারপর Haskell, অভিযোগ করবে এটা টাইপ অনুমান পারে না:

main = do n <- readLn
          print n
-- this program results in a compile-time error "Unresolved top-level overloading"

আমি যে প্রকারটি চাই তা উল্লেখ করে আমি অস্পষ্টতাকে সমাধান করতে পারি:

main = do n <- readLn
          print (n::Int)
-- this compiles (and does what I want)

যাইহোক, এই পুরো আলোচনার অর্থ কী তা হ'ল রিটার্ন ভ্যালু দ্বারা ওভারলোডিং সম্ভব এবং এটি সম্পন্ন হয়েছে, যা আপনার প্রশ্নের অংশের উত্তর দেয়।

আপনার প্রশ্নের অন্য অংশটি কেন আরও বেশি ভাষা তা করে না। আমি অন্যদের উত্তর দিতে হবে। তবে কয়েকটি মন্তব্য: মূল কারণটি হ'ল যুক্তির ধরণের মাধ্যমে ওভারলোডিংয়ের চেয়ে বিভ্রান্তির সুযোগটি সত্যই এখানে বেশি। আপনি স্বতন্ত্র ভাষা থেকে যুক্তিগুলিও দেখতে পারেন:

অ্যাডা : "এটি উপস্থিত হতে পারে যে সহজতম ওভারলোড রেজোলিউশন নিয়মটি হ'ল ওভারলোডেড রেফারেন্সটি সমাধান করার জন্য - যতটা সম্ভব প্রাসঙ্গিক থেকে সমস্ত তথ্য - ব্যবহার করা This এই নিয়মটি সহজ হতে পারে তবে এটি সহায়ক নয় It এটি মানব পাঠকের প্রয়োজন লেখার বড় আকারের টুকরো স্ক্যান করতে, এবং উপরের স্বেচ্ছাসেবী জটিল সূচনাগুলি (যেমন (ছ)) তৈরি করা আমাদের বিশ্বাস, আমরা বিশ্বাস করি যে একটি ভাল নিয়ম এমনটি যা স্পষ্ট করে তোলে যা একজন পাঠক বা সংকলককে অবশ্যই সম্পাদন করতে হবে, এবং এটি এই কাজটি করে তোলে মানুষের পাঠকের পক্ষে যতটা সম্ভব প্রাকৃতিক "

সি ++ (বার্জন স্ট্রোস্ট্রপের "দ্য সি ++ প্রোগ্রামিং ল্যাঙ্গুয়েজ" এর 7 অনুচ্ছেদ): "ওভারলোড রেজোলিউশনে রিটার্নের ধরণগুলি বিবেচনা করা হয় না The কারণটি কোনও পৃথক অপারেটর বা ফাংশন কল প্রসঙ্গে স্বাধীন রাখার জন্য রেজোলিউশন রাখে Consider বিবেচনা করুন:

float sqrt(float);
double sqrt(double);

void f(double da, float fla)
{
    float fl = sqrt(da);     // call sqrt(double)
    double d = sqrt(da); // call sqrt(double)
    fl = sqrt(fla);            // call sqrt(float)
    d = sqrt(fla);             // call sqrt(float)
}

যদি রিটার্নের ধরনটি বিবেচনায় নেওয়া হয়, তবে sqrt()বিচ্ছিন্নতার ডাকটি দেখার জন্য এবং কোন ফাংশনটি ডাকা হয়েছিল তা নির্ধারণ করা আর সম্ভব হবে না "" (দ্রষ্টব্য, তুলনা করার জন্য, হাসকেলে কোনও অন্তর্নিহিত রূপান্তর নেই ))

জাভা ( জাভা ভাষার স্পেসিফিকেশন 9.4.1 ): "উত্তরাধিকারসূত্রে প্রাপ্ত পদ্ধতিগুলির মধ্যে একটি অবশ্যই অন্য উত্তরাধিকারসূত্রে প্রাপ্ত পদ্ধতির জন্য রিটার্ন-টাইপ-সাবস্টিটিউটেবল হতে হবে, অন্যথায় একটি সংকলন-সময় ত্রুটি ঘটে" " (হ্যাঁ, আমি জানি এটি একটি যৌক্তিকতা দেয় না I'm আমি নিশ্চিত যে "জাভা প্রোগ্রামিং ল্যাঙ্গুয়েজ") গোসলিংয়ের পক্ষ থেকে যুক্তিটি দেওয়া হয়েছিল someone সম্ভবত কারও একটি অনুলিপি আছে? আমি বাজি ধরেছি এটি মূলত "সর্বনিম্ন আশ্চর্যতার মূলনীতি"। ) তবে জাভা সম্পর্কে মজাদার ঘটনা: জেভিএম রিটার্ন ভ্যালু দিয়ে ওভারলোডিংয়ের অনুমতি দেয় ! উদাহরণস্বরূপ, স্কালায় এটি ব্যবহার করা হয় এবং জাভা দিয়ে সরাসরি ইন্টার্নাল দিয়ে ঘুরে বেড়ানো যায়।

পুনশ্চ. চূড়ান্ত নোট হিসাবে, আসলে একটি কৌশল দিয়ে সি ++ এ রিটার্ন মান দ্বারা ওভারলোড করা সম্ভব। সাক্ষী:

struct func {
    operator string() { return "1";}
    operator int() { return 2; }
};

int main( ) {
    int x    = func(); // calls int version
    string y = func(); // calls string version
    double d = func(); // calls int version
    cout << func() << endl; // calls int version
    func(); // calls neither
}

দুর্দান্ত পোস্ট, তবে আপনি পড়তে (স্ট্রিং -> কিছু) কী তা পরিষ্কার করতে পারেন।
টমাস এডিং

সি ++ আপনাকে কনট্রাস্ট / নট কনস্ট ফেরত মান দ্বারা ওভারলোড দেয়। stackoverflow.com/questions/251159/…
জিওন

3
জবরদস্তি অপারেটরদের ওভারলোড করার সাথে আপনার শেষ কৌতুকের জন্য, "কোট" লাইন কখনও কখনও কাজ করে তবে কোডটিতে আমি প্রায় কোনও পরিবর্তনই "অপারেটর <<" "এর জন্য অস্পষ্ট ওভারলোড দেয়।
স্টিভ

1
আমি যে পদ্ধতির পক্ষপাত করব তা হ'ল একটি ওভারলোডকে "পছন্দসই" হিসাবে চিহ্নিত করা প্রয়োজন; সংকলকটি কেবলমাত্র পছন্দসই ওভারলোডগুলি ব্যবহার করে বাঁধাইয়ের মাধ্যমে শুরু হবে এবং তারপরে নির্ধারণ করুন যে কোনও অ-পছন্দসই ওভারলোডগুলি উন্নতি হবে কিনা। অন্যান্য বিষয়গুলির মধ্যে, ধরুন ধরণের Fooএবং Barসমর্থন দ্বিদলীয় রূপান্তরকরণ এবং কোনও পদ্ধতি Fooঅভ্যন্তরীণভাবে টাইপ ব্যবহার করে তবে রিটার্ন টাইপ ব্যবহার করে Bar। যদি এই জাতীয় পদ্ধতিটি কোড দ্বারা কল করা হয় যা তাৎক্ষণিকভাবে ফলাফলটি টাইপ করতে বাধ্য Fooকরে, Barরিটার্ন টাইপ ব্যবহার করে কাজ Fooকরতে পারে তবে এটি আরও ভাল। বিটিডাব্লু, আমি একটি
উপায়ও

... একটি পদ্ধতি যেমন কোন কনস্ট্রাক্টে কী ধরণের ব্যবহার করা উচিত তা নির্ধারণ করতে পারে var someVar = someMethod();(বা অন্যথায় নির্ধারণ করুন যে এর ফিরতিটি এ জাতীয় ফ্যাশনে ব্যবহার করা উচিত নয়)। উদাহরণস্বরূপ, প্রবাহের ইন্টারফেস প্রয়োগকারী প্রকারের পরিবারগুলি পরিবর্তনীয় এবং অপরিবর্তনীয় সংস্করণ থাকার ফলে উপকৃত হতে পারে, সুতরাং কোনও পরিবর্তনীয় বস্তুর অনুলিপি করতে var thing2 = thing1.WithX(3).WithY(5).WithZ(9);হবে , এক্স পরিবর্তন করতে পারে এবং সেই পরিবর্তনীয় বস্তুটি ফিরিয়ে দিতে পারে; Y কে রূপান্তরিত করবে এবং একই বস্তুটি ফিরিয়ে দেবে; একইভাবে `উইথজেড (9)। তারপরে অ্যাসাইনমেন্টটি একটি অপরিবর্তনীয় ধরণের রূপান্তরিত হবে। WithX(3)thing1WithY(5)
সুপারক্যাট

37

যদি ফাংশনগুলি রিটার্নের ধরণের মাধ্যমে ওভারলোড হয় এবং আপনার এই দুটি ওভারলোড ছিল

int func();
string func();

এই দুটি কল দেখে এই দুটি ফাংশনগুলির মধ্যে কোনটি কল করতে হবে তা সংকলকটি বের করার কোনও উপায় নেই

void main() 
{
    func();
}

এই কারণে, ভাষা ডিজাইনাররা প্রায়শই রিটার্ন-ভ্যালু ওভারলোডিংকে অস্বীকার করে।

কিছু কিছু ভাষায় (যেমন MSIL হিসাবে), কিন্তু, না রিটার্ন টাইপ দ্বারা ওভারলোডিং অনুমতি দেয়। তারাও অবশ্যই উপরোক্ত অসুবিধার মুখোমুখি হয়, তবে তাদের কার্যকারিতা রয়েছে, যার জন্য আপনাকে তাদের ডকুমেন্টেশনের সাথে পরামর্শ করতে হবে।


4
একটি সামান্য বাচ্চা (আপনার উত্তর একটি খুব স্পষ্ট, বোধগম্য যুক্তি দেয়): এটি উপায় নেই যে; এটি বেশিরভাগ লোকের চেয়ে উপায়গুলি আনাড়ি এবং আরও বেদনাদায়ক that উদাহরণস্বরূপ, সি ++ এ ওভারলোড সম্ভবত কিছু কুরুচিপূর্ণ কাস্ট সিনট্যাক্স ব্যবহার করে সমাধানযোগ্য হবে।
মাইকেল বুড়

2
@ জার্গ ডব্লু মিতাগ: ফাংশনগুলি কী করে তা আপনি দেখতে পাচ্ছেন না। তাদের সহজেই বিভিন্ন পার্শ্ব প্রতিক্রিয়া হতে পারে ।
এ। রেক্স

2
@ জার্গ - বেশিরভাগ মূলধারার প্রোগ্রামিং ভাষায় (সি / সি ++, সি #, জাভা ইত্যাদি) ফাংশনে সাধারণত পার্শ্ব প্রতিক্রিয়া থাকে। প্রকৃতপক্ষে, আমি অনুমান করতে পারি যে পার্শ্ব প্রতিক্রিয়াযুক্ত ফাংশনগুলি কমপক্ষে সেগুলি ছাড়া কম সাধারণ।
মাইকেল বুড় 21

6
এখানে দেরি করে লাফিয়ে উঠছে, তবে কিছু প্রসঙ্গে "ফাংশন" এর সংকীর্ণ সংজ্ঞা রয়েছে (মূলত) "কোনও পার্শ্ব প্রতিক্রিয়া ছাড়াই একটি পদ্ধতি"। আরও কথোপকথন হিসাবে, "ফাংশন" প্রায়শই "পদ্ধতি" বা "সাব্রোটিন" এর সাথে বিনিময়যোগ্য হিসাবে ব্যবহৃত হয়। জর্গ হয় আপনার দৃষ্টিভঙ্গির উপর নির্ভর করে কঠোর বা
পেডেন্টিক হয়

3
এমনকি পরে জাম্পিং, কিছু দৃষ্টিকোণ কঠোর বা পেডেন্টিক ছাড়াও বিশেষণ ব্যবহার করতে পারে
প্যাট্রিক ম্যাকডোনাল্ড

27

এই জাতীয় ভাষায়, আপনি কীভাবে নিম্নলিখিতগুলি সমাধান করবেন:

f(g(x))

যদি foverloads ছিল void f(int)এবং void f(string)এবং goverloads ছিল int g(int)এবং string g(int)? আপনার এক ধরণের ডিস্যামিগিগুয়েটার দরকার।

আমি মনে করি যে পরিস্থিতিতে আপনার এটির প্রয়োজন হতে পারে ফাংশনের জন্য একটি নতুন নাম চয়ন করে আরও ভাল পরিবেশিত হবে।


2
নিয়মিত ধরণের ওভারলোডিংয়ের ফলে অস্পষ্টতাও দেখা দিতে পারে। আমি মনে করি প্রয়োজনীয় কাস্টগুলির সংখ্যা গণনা করে এগুলি সাধারণত সমাধান করা হয় তবে এটি সর্বদা কার্যকর হয় না।
জে কনরোড

1
হ্যাঁ, স্ট্যান্ডার্ড রূপান্তরগুলি সঠিক ম্যাচ, প্রচার এবং রূপান্তরগুলিতে স্থান পেয়েছে: অকার্যকর এফ (ইন্ট); অকার্যকর চ (দীর্ঘ); চ ( 'একটি'); কল এফ (ইন্ট), কারণ এটি কেবলমাত্র প্রচার, যখন দীর্ঘতে রূপান্তরিত হয় রূপান্তর। অকার্যকর চ (ভাসা); অকার্যকর চ (সংক্ষিপ্ত); চ (10); উভয়ের জন্য রূপান্তর প্রয়োজন: কলটি অস্পষ্ট।
জোহানেস স্কাউব - লিটব

যদি ভাষাটির অলস মূল্যায়ন হয় তবে এটি কোনও সমস্যা নয়।

আপভোট, প্যারামিটার ধরণের ওভারলোডিং এবং রিটার্ন টাইপ ওভারলোডিংয়ের মিথস্ক্রিয়াটিকে রেক্সের পোস্টে সম্বোধন করা হয়নি। খুব ভাল পয়েন্ট।
জোসেফ গারভিন

1
আমি যদি কোনও ভাষা ডিজাইনি করতাম, আমার নিয়মটি হ'ল যে কোনও ওভারলোডেড ফাংশনের জন্য, প্রতিটি প্যারামিটার স্বাক্ষরে অবশ্যই একটি রিটার্ন-টাইপ ডিফল্ট হিসাবে মনোনীত করা উচিত; একটি সংকলক প্রতিটি ফাংশন কল ডিফল্ট টাইপ ব্যবহার করবে তা ধরে নিয়ে শুরু হবে would একবার এটি হয়ে গেলে, তবে প্রতিটি পরিস্থিতিতে যেখানে কোনও ফাংশনের রিটার্ন মান তাত্ক্ষণিকভাবে নিক্ষেপ করা হয়েছিল বা অন্য কোনও কিছুতে জোর করা হয়েছিল, সংকলকটি একটি ওভারলোডের জন্য যাচাই করবে যার প্যারামিটারের স্বাক্ষর অভিন্ন, তবে যার রিটার্নের ধরণটি আরও ভাল ম্যাচ (বা সম্ভবত বাতিল) । আমি সম্ভবত এই ধরনের ওভারলোডগুলির জন্য একটি "ওভাররাইড-ওয়ানরাইড - সমস্ত" বিধি আরোপ করব।
সুপারক্যাট

19

অন্য একটি খুব অনুরূপ প্রশ্ন (ডুপ?) থেকে একটি সি ++ নির্দিষ্ট উত্তর চুরি করতে :


ওভারলোড রেজোলিউশনে ফাংশন রিটার্নের ধরনগুলি কার্যকর হয় না কারণ স্ট্রোস্ট্রাপ (আমি অন্যান্য সি ++ আর্কিটেক্টের ইনপুট নিয়ে ধরে নিয়েছি) ওভারলোড রেজোলিউশনটিকে 'প্রসঙ্গত স্বাধীন' হতে চেয়েছিলেন। 7.4.1 দেখুন - "ওভারলোডিং এবং রিটার্নের ধরণ" "সি ++ প্রোগ্রামিং ভাষা, তৃতীয় সংস্করণ" থেকে।

কারণটি হ'ল কোনও পৃথক অপারেটর বা ফাংশন কলের প্রসঙ্গটি-স্বতন্ত্রের জন্য রেজোলিউশন রাখা।

তারা চেয়েছিল যে কেবল ওভারলোডটি কীভাবে ডাকা হয়েছিল - ফলাফল কীভাবে ব্যবহৃত হয়েছিল তা নয় (এটি যদি একেবারেই ব্যবহৃত হয়) তবেই এটি ভিত্তিক করা উচিত। প্রকৃতপক্ষে, ফলাফলকে ব্যবহার না করেই অনেকগুলি ক্রিয়াকলাপ ডাকা হয় বা ফলাফলটি বৃহত্তর অভিব্যক্তির অংশ হিসাবে ব্যবহৃত হত। আমি নিশ্চিত যে একটি কারণ যখন তারা এই সিদ্ধান্ত নিয়েছিল তখন তা হ'ল যে রিটার্নের ধরণটি যদি রেজোলিউশনের অংশ হয় তবে ওভারলোডেড ফাংশনগুলির জন্য অনেকগুলি কল আসত যেগুলি জটিল বিধি দ্বারা সমাধান করতে হবে বা সংকলক নিক্ষেপ করতে হবে কলটি অস্পষ্ট ছিল এমন একটি ত্রুটি।

এবং, লর্ড জানেন, সি ++ ওভারলোড রেজোলিউশন যথেষ্ট জটিল কারণ এটি দাঁড়িয়েছে ...


5

হ্যাশকেলে এটি ফাংশন ওভারলোডিং না থাকলেও এটি সম্ভব। হাস্কেল টাইপ ক্লাস ব্যবহার করে। একটি প্রোগ্রামে আপনি দেখতে পারেন:

class Example a where
    example :: Integer -> a

instance Example Integer where  -- example is now implemented for Integer
    example :: Integer -> Integer
    example i = i * 10

ফাংশন ওভারলোডিং নিজেই এত জনপ্রিয় নয়। বেশিরভাগ ভাষা আমি এর সাথে দেখেছি হ'ল সি ++, সম্ভবত জাভা এবং / অথবা সি #। সমস্ত গতিশীল ভাষায় এটি একটি সংক্ষিপ্তকরণ:

define example:i
  ↑i type route:
    Integer = [↑i & 0xff]
    String = [↑i upper]


def example(i):
    if isinstance(i, int):
        return i & 0xff
    elif isinstance(i, str):
        return i.upper()

সুতরাং এটিতে খুব একটা পয়েন্ট নেই। ভাষা আপনি যেখানেই এটি ব্যবহার করেন না কেন সেখানে একটি লাইন ফেলে দিতে আপনাকে সহায়তা করতে পারে কিনা তা বেশিরভাগ লোকই আগ্রহী নয়।

প্যাটার্ন মেলানো ফাংশন ওভারলোডিংয়ের সাথে কিছুটা মিল এবং আমার ধারণা কখনও কখনও একইভাবে কাজ করা হয়। এটি সাধারণ নয় যদিও এটি কেবল কয়েকটি প্রোগ্রামের জন্যই কার্যকর এবং বেশিরভাগ ভাষায় এটি প্রয়োগ করা কৃপণ।

আপনি দেখতে পান যে ভাষাতে প্রয়োগ করার জন্য আরও অনেক সহজ-কার্যকর-বাস্তবায়ন বৈশিষ্ট্য রয়েছে যার মধ্যে রয়েছে:

  • গতিশীল টাইপিং
  • তালিকা, অভিধান এবং ইউনিকোড স্ট্রিংয়ের অভ্যন্তরীণ সমর্থন
  • অপ্টিমাইজেশন (জেআইটি, টাইপ ইনফারেন্সিং, সংকলন)
  • ইন্টিগ্রেটেড ডিপ্লোমেন্ট সরঞ্জামসমূহ
  • লাইব্রেরি সমর্থন
  • সম্প্রদায় সমর্থন এবং জমায়েত স্থান
  • সমৃদ্ধ স্ট্যান্ডার্ড লাইব্রেরি
  • ভাল বাক্য গঠন
  • ইভাল প্রিন্ট লুপ পড়ুন
  • প্রতিফলিত প্রোগ্রামিং জন্য সমর্থন

3
হাস্কেলের ওভারলোডিং রয়েছে। প্রকারের ক্লাসগুলি হল ভাষা বৈশিষ্ট্য যা অতিরিক্ত লোড ফাংশনগুলি সংজ্ঞায়িত করতে ব্যবহৃত হয়।
লি

2

ভাল উত্তর! বিশেষত A.Rex এর উত্তর খুব বিশদ এবং শিক্ষণীয়। তিনি উল্লেখ করেছেন যে, সি ++ সংকলন করার সময় ব্যবহারকারী-সরবরাহিত টাইপ-রূপান্তর অপারেটরগুলি বিবেচনা করে lhs = func(); (যেখানে ফানক সত্যই কোনও কাঠামোর নাম) । আমার কাজের দিকটি কিছুটা আলাদা - এর চেয়ে ভাল নয়, কেবল আলাদা (যদিও এটি একই বেসিক ধারণার উপর ভিত্তি করে)।

যেখানে আমি লিখতে চেয়েছিলাম ...

template <typename T> inline T func() { abort(); return T(); }

template <> inline int func()
{ <<special code for int>> }

template <> inline double func()
{ <<special code for double>> }

.. etc, then ..

int x = func(); // ambiguous!
int x = func<int>(); // *also* ambiguous!?  you're just being difficult, g++!

আমি এমন একটি সমাধান দিয়ে শেষ করেছি যা প্যারামিটারাইজড স্ট্রাক্ট ব্যবহার করে (টি = রিটার্নের ধরণ সহ):

template <typename T>
struct func
{
    operator T()
    { abort(); return T(); } 
};

// explicit specializations for supported types
// (any code that includes this header can add more!)

template <> inline
func<int>::operator int()
{ <<special code for int>> }

template <> inline
func<double>::operator double()
{ <<special code for double>> }

.. etc, then ..

int x = func<int>(); // this is OK!
double d = func<double>(); // also OK :)

এই সমাধানটির একটি সুবিধা হ'ল যে কোনও কোডে এই টেমপ্লেট সংজ্ঞা রয়েছে সেগুলি আরও ধরণের জন্য আরও বিশেষত্ব যুক্ত করতে পারে। এছাড়াও আপনি প্রয়োজন হিসাবে কাঠামোর আংশিক বিশেষজ্ঞ করতে পারেন। উদাহরণস্বরূপ, আপনি যদি পয়েন্টারের ধরণের জন্য বিশেষ পরিচালনা করতে চান:

template <typename T>
struct func<T*>
{
    operator T*()
    { <<special handling for T*>> } 
};

নেতিবাচক হিসাবে, আপনি int x = func();আমার সমাধান দিয়ে লিখতে পারবেন না । আপনাকে লিখতে হবে int x = func<int>();। সংকলনকারীকে টাইপ রূপান্তর অপারেটরগুলির দিকে তাকিয়ে জিজ্ঞাসা করার পরিবর্তে আপনাকে পরিষ্কারভাবে বলতে হবে যে রিটার্নের ধরনটি কী। আমি বলব যে "আমার" সমাধান এবং এআরেক্স এর দু'জনেই এই সি ++ দ্বিধা মোকাবেলা করার উপায়গুলির একটি প্যারেটো-সর্বোত্তম সামনে রয়েছে :)


1

যদি আপনি বিভিন্ন রিটার্নের ধরণের সাহায্যে ওভারলোড পদ্ধতিগুলি দেখতে চান , তবে ওভারলোড কার্যকরকরণের অনুমতি দেওয়ার জন্য কেবলমাত্র একটি ডামি প্যারামিটার যুক্ত করুন , তবে ভুলে যাবেন না প্যারামিটারের ধরনটি আলাদা হওয়া উচিত যাতে ওভারলোডের যুক্তি পরবর্তী কাজ করে যেমন ডেল্ফির ক্ষেত্রে:

type    
    myclass = class
    public
      function Funct1(dummy: string = EmptyStr): String; overload;
      function Funct1(dummy: Integer = -1): Integer; overload;
    end;

এটি এটি ব্যবহার করুন

procedure tester;
var yourobject : myclass;
  iValue: integer;
  sValue: string;
begin
  yourobject:= myclass.create;
  iValue:= yourobject.Funct1(); //this will call the func with integer result
  sValue:= yourobject.Funct1(); //this will call the func with string result
end;

এটি একটি ভয়ানক ধারণা। ডামি পরামিতিগুলি প্রবর্তন করবেন না, এটি একটি বড় কোডের গন্ধ। পরিবর্তে, বিভিন্ন নাম চয়ন করুন, বা এমন একটি রিটার্নের ধরন চয়ন করুন যা এর মতো কাজ করতে পারে বা একটি বৈষম্যমূলক ইউনিয়ন বা কিছু something
হাবেল

@ আবেল আপনি যা পরামর্শ দিচ্ছেন তা আসলে ভয়ঙ্কর ধারণা, কারণ পুরো ধারণাটি এই ডামি প্যারামিটার সম্পর্কে, এবং বিকাশকারীকে এটি পরিষ্কার করার জন্য এটির নামকরণ করা হয়েছিল যে এই পরামিতিটি ডামি এবং এটিকে অবহেলা করা উচিত, আপনি যদি এই ক্ষেত্রে থাকেন তবে জানেন না ডিফল্ট মানগুলির সাথে ডামি প্যারামিটারগুলি অনেক লাইব্রেরিতে, ডেল্ফিতে ভিসিএল, এবং অনেক আইডিই ব্যবহৃত হয়, উদাহরণস্বরূপ ডেল্ফিতে আপনি এটি সেফলোয়াড লাইব্রেরির সিসটিল্ট ইউনিটে দেখতে পাচ্ছেন ...
জোরো_ব্লানকো

মানচিত্র বা ভাঁজ অপারেশনগুলিতে ল্যাম্বডাসের মতো, বা কোনও ইন্টারফেস প্রয়োগ করার সময় ডামি প্যারামিটারগুলি কার্যকর এমন পরিস্থিতিতেও রয়েছে। তবে কেবল একটি ওভারলোড তৈরি করার জন্য, না, আমি অসম্মতি জানাতে চাই। কোনও প্রয়োজন নেই এবং এটি আওয়াজ রয়েছে যা প্রোগ্রামাররা ছাড়া বাঁচতে পারে।
হাবিল

0

ইতিমধ্যে দেখানো হয়েছে - কোনও ফাংশনের অস্পষ্ট কল যা কেবলমাত্র রিটার্ন টাইপের দ্বারা পৃথক হয় অস্পষ্টতার পরিচয় দেয়। অস্পষ্টতা ত্রুটিযুক্ত কোড প্ররোচিত করে। ত্রুটিযুক্ত কোড অবশ্যই এড়ানো উচিত।

অস্পষ্টতার প্রয়াস দ্বারা চালিত জটিলতা দেখায় যে এটি ভাল হ্যাক নয়। বৌদ্ধিক অনুশীলন ছাড়াও - কেন রেফারেন্স প্যারামিটারগুলি সহ পদ্ধতিগুলি ব্যবহার করবেন না।

procedure(reference string){};
procedure(reference int){};
string blah;
procedure(blah)

কারণ আপনি তত্ক্ষণাত্ "রিটার্ন" মানগুলি সহজে ব্যবহার করতে পারবেন না। এর বিপরীতে আপনাকে একক লাইনে প্রতিটি কল করতে হবেdoing(thisVery(deeplyNested(), andOften(butNotAlways()), notReally()), goodCode());
অ্যাডোরাথ

0

এই ওভারলোডিং বৈশিষ্ট্যটি পরিচালনা করা কঠিন নয়, যদি আপনি এটি কিছুটা ভিন্ন উপায়ে দেখেন। নিম্নোক্ত বিবেচনা কর,

public Integer | String f(int choice){
if(choice==1){
return new string();
}else{
return new Integer();
}}

যদি কোনও ভাষা ওভারলোডিং ফিরিয়ে দেয় তবে এটি প্যারামিটারকে ওভারলোডিংয়ের অনুমতি দেবে, তবে সদৃশ নয়। এটি এর সমস্যার সমাধান করবে:

main (){
f(x)
}

কারণ চয়ন করার জন্য কেবলমাত্র একটি (চ পছন্দ) রয়েছে।


0

.NET- এ, কখনও কখনও আমরা জেনেরিক ফলাফল থেকে পছন্দসই আউটপুট নির্দেশ করতে একটি প্যারামিটার ব্যবহার করি এবং তারপরে আমরা যা প্রত্যাশা করি তা পেতে একটি রূপান্তর তৈরি করি।

সি শার্প

public enum FooReturnType{
        IntType,
        StringType,
        WeaType
    }

    class Wea { 
        public override string ToString()
        {
            return "Wea class";
        }
    }

    public static object Foo(FooReturnType type){
        object result = null;
        if (type == FooReturnType.IntType) 
        {
            /*Int related actions*/
            result = 1;
        }
        else if (type == FooReturnType.StringType)
        {
            /*String related actions*/
            result = "Some important text";
        }
        else if (type == FooReturnType.WeaType)
        {
            /*Wea related actions*/
            result = new Wea();
        }
        return result;
    }

    static void Main(string[] args)
    {
        Console.WriteLine("Expecting Int from Foo: " + Foo(FooReturnType.IntType));
        Console.WriteLine("Expecting String from Foo: " + Foo(FooReturnType.StringType));
        Console.WriteLine("Expecting Wea from Foo: " + Foo(FooReturnType.WeaType));
        Console.Read();
    }

সম্ভবত এই উদাহরণটি সাহায্য করতে পারে:

সি ++

    #include <iostream>

enum class FooReturnType{ //Only C++11
    IntType,
    StringType,
    WeaType
}_FooReturnType;

class Wea{
public:
    const char* ToString(){
        return "Wea class";
    }
};

void* Foo(FooReturnType type){
    void* result = 0;
    if (type == FooReturnType::IntType) //Only C++11
    {
        /*Int related actions*/
        result = (void*)1;
    }
    else if (type == FooReturnType::StringType) //Only C++11
    {
        /*String related actions*/
        result = (void*)"Some important text";
    }
    else if (type == FooReturnType::WeaType) //Only C++11
    {
        /*Wea related actions*/
        result = (void*)new Wea();
    }
    return result;
}

int main(int argc, char* argv[])
{
    int intReturn = (int)Foo(FooReturnType::IntType);
    const char* stringReturn = (const char*)Foo(FooReturnType::StringType);
    Wea *someWea = static_cast<Wea*>(Foo(FooReturnType::WeaType));
    std::cout << "Expecting Int from Foo: " << intReturn << std::endl;
    std::cout << "Expecting String from Foo: " << stringReturn << std::endl;
    std::cout << "Expecting Wea from Foo: " << someWea->ToString() << std::endl;
    delete someWea; // Don't leak oil!
    return 0;
}

1
এটি হ্যাকিশের মতো এবং এটি যদি ব্যবহারকারী সঠিকভাবে ফলাফলটি না দেয়, বা বিকাশকারী সঠিকভাবে এনামের সাথে রিটার্নের সাথে মেলে না তবে রান-টাইমের ত্রুটি হতে পারে। আমি এই উত্তর
স্ল্যাব্ল্যাঙ্ক

0

রেকর্ডের জন্য, অ্যাক্টেভ রিটার্ন উপাদান অনুসারে স্কেলারার বনাম অ্যারে অনুসারে বিভিন্ন ফলাফলের অনুমতি দেয়।

x = min ([1, 3, 0, 2, 0])
   ⇒  x = 0

[x, ix] = min ([1, 3, 0, 2, 0])
   ⇒  x = 0
      ix = 3 (item index)

সিএফ এছাড়াও একক মান পচন


0

এটি সি ++ এর জন্য কিছুটা আলাদা; এটি সরাসরি রিটার্ন টাইপের মাধ্যমে ওভারলোডিং হিসাবে বিবেচিত হবে কিনা আমি জানি না। এটি এমন একটি টেম্পলেট বিশেষীকরণ যা পদ্ধতিতে কাজ করে।

util.h

#ifndef UTIL_H
#define UTIL_H

#include <string>
#include <sstream>
#include <algorithm>

class util {
public: 
    static int      convertToInt( const std::string& str );
    static unsigned convertToUnsigned( const std::string& str );
    static float    convertToFloat( const std::string& str );
    static double   convertToDouble( const std::string& str );

private:
    util();
    util( const util& c );
    util& operator=( const util& c );

    template<typename T>
    static bool stringToValue( const std::string& str, T* pVal, unsigned numValues );

    template<typename T>
    static T getValue( const std::string& str, std::size_t& remainder );
};

#include "util.inl"

#endif UTIL_H

util.inl

template<typename T>
static bool util::stringToValue( const std::string& str, T* pValue, unsigned numValues ) {
    int numCommas = std::count(str.begin(), str.end(), ',');
    if (numCommas != numValues - 1) {
        return false;
    }

    std::size_t remainder;
    pValue[0] = getValue<T>(str, remainder);

    if (numValues == 1) {
        if (str.size() != remainder) {
            return false;
        }
    }
    else {
        std::size_t offset = remainder;
        if (str.at(offset) != ',') {
            return false;
        }

        unsigned lastIdx = numValues - 1;
        for (unsigned u = 1; u < numValues; ++u) {
            pValue[u] = getValue<T>(str.substr(++offset), remainder);
            offset += remainder;
            if ((u < lastIdx && str.at(offset) != ',') ||
                (u == lastIdx && offset != str.size()))
            {
                return false;
            }
        }
    }
    return true;    
}

util.cpp

#include "util.h"

template<>
int util::getValue( const std::string& str, std::size_t& remainder ) {
    return std::stoi( str, &remainder );
} 

template<>
unsigned util::getValue( const std::string& str, std::size_t& remainder ) {
    return std::stoul( str, &remainder );
}

template<>
float util::getValue( const std::string& str, std::size_t& remainder ) {
    return std::stof( str, &remainder );
}     

template<>   
double util::getValue( const std::string& str, std::size_t& remainder ) {
    return std::stod( str, &remainder );
}

int util::convertToInt( const std::string& str ) {
    int i = 0;
    if ( !stringToValue( str, &i, 1 ) ) {
        std::ostringstream strStream;
        strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to int";
        throw strStream.str();
    }
    return i;
}

unsigned util::convertToUnsigned( const std::string& str ) {
    unsigned u = 0;
    if ( !stringToValue( str, &u, 1 ) ) {
        std::ostringstream strStream;
        strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to unsigned";
        throw strStream.str();
    }
    return u;
}     

float util::convertToFloat(const std::string& str) {
    float f = 0;
    if (!stringToValue(str, &f, 1)) {
        std::ostringstream strStream;
        strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to float";
        throw strStream.str();
    }
    return f;
}

double util::convertToDouble(const std::string& str) {
    float d = 0;
    if (!stringToValue(str, &d, 1)) {
        std::ostringstream strStream;
        strStream << __FUNCTION__ << " Bad conversion of [" << str << "] to double";
        throw strStream.str();
    }
    return d;
}

এই উদাহরণটি হ'ল রিটার্ন টাইপের মাধ্যমে ফাংশন ওভারলোড রেজোলিউশনটি ব্যবহার করছে না, তবে এই সি ++ নন অবজেক্ট ক্লাসটি কোনও প্রাইভেট স্ট্যাটিক পদ্ধতিতে রিটার্ন টাইপের মাধ্যমে ফাংশন ওভারলোড রেজোলিউশন অনুকরণ করতে টেম্পলেট বিশেষায়িতকরণ ব্যবহার করছে।

প্রতিটি convertToTypeফাংশন ফাংশন টেমপ্লেটকে কল করছে stringToValue()এবং যদি আপনি এই ফাংশন টেম্পলেটটির প্রয়োগকরণের বিবরণ বা অ্যালগরিদমটি দেখেন তবে এটি কল করছে getValue<T>( param, param )এবং এটি কোনও প্রকার ফিরে পাচ্ছে এবং এটিকে একটি পরামিতি হিসাবে ফাংশন টেম্পলেটে পাস করা হয়েছে যা Tএটিতে সংরক্ষণ করছে ।T*stringToValue()

এ জাতীয় কিছু ব্যতীত; রি + টাইপ অনুসারে ফাংশন ওভারলোডিং রেজোলিউশন করার জন্য সি ++ এর আসলেই কোনও ব্যবস্থা নেই। অন্যান্য কন্সট্রাক্টস বা মেকানিজম থাকতে পারে যা সম্পর্কে আমি অবগত নই যে রিটার্ন টাইপের মাধ্যমে রেজুলেশন সিমুলেট করতে পারে।


-1

আমি মনে করি এটি আধুনিক সি ++ সংজ্ঞায় একটি জিএপি ... কেন?

int func();
double func();

// example 1. → defined
int i = func();

// example 2. → defined
double d = func();

// example 3. → NOT defined. error
void main() 
{
    func();
}

কেন একটি সি ++ সংকলক উদাহরণস্বরূপ "3" তে ত্রুটি ফেলতে পারে না এবং কোডটিকে "1 + 2" উদাহরণ হিসাবে গ্রহণ করতে পারে ??


হ্যাঁ, তারা এই সময়ে সি # (এবং সম্ভবত সি ++) এর জন্য বিবেচনা করেছেন। তবে আপনার কোডটি তুচ্ছ, যখন আপনি শ্রেণিবদ্ধতা, ভার্চুয়াল পদ্ধতি, বিমূর্তি এবং ইন্টারফেসগুলি, অন্যান্য ওভারলোডগুলি এবং কখনও কখনও একাধিক উত্তরাধিকার যোগ করেন, কোন পদ্ধতিটি সমাধান করা উচিত তা সিদ্ধান্ত নিতে খুব দ্রুত জটিল হয়ে যায়। ডিজাইনারদের সেই পথটি না যাওয়ার পছন্দ, তবে অন্যান্য ভাষা সাফল্যের বিভিন্ন স্তরে আলাদাভাবে সিদ্ধান্ত নিয়েছে।
হাবেল

-2

বেশিরভাগ স্থির ভাষাও এখন জেনেরিকগুলি সমর্থন করে, যা আপনার সমস্যার সমাধান করবে। যেমন আগেই বলা হয়েছে, প্যারামিটারের পার্থক্য না থাকলে, কোনটি কল করতে হবে তা জানার উপায় নেই। সুতরাং আপনি যদি এটি করতে চান তবে কেবল জেনেরিকগুলি ব্যবহার করুন এবং এটিকে একটি দিন কল করুন।


একই জিনিস না। আপনি কীভাবে এমন কোনও ফাংশন পরিচালনা করতে পারবেন যা কোনও পূর্ণসংখ্যা, ভাসা, বুল বা রিটার্নের ধরণটি কীভাবে ব্যবহৃত হয় তার ভিত্তিতে যেকোন কিছুতে ইনপুট অনুবাদ করে? আপনার প্রত্যেকের জন্য একটি বিশেষ কেস প্রয়োজন তাই এটি সাধারণীকরণ করা যায় না।
জে কনরোড

" রিটার্নের ধরণে ওভারলোডিং" এর জন্য একটি চতুর কৌশলটির জন্য কোডেপ্রজেক্ট / কেবি / সিপি / রিটার্নওভারলোড.এএসপিএক্স দেখুন । মূলত, একটি ফাংশন ফানক () সংজ্ঞায়নের পরিবর্তে আপনি একটি স্ট্রাক ফানক সংজ্ঞায়িত করেন, একে অপারেটর () () () এবং প্রতিটি উপযুক্ত ধরণের রূপান্তর দিন।
j_random_hacker

জে, আপনি ফাংশনটি কল করার সময় আপনি রিটার্নের ধরণটি সংজ্ঞায়িত করেন। যদি ইনপাসটি পৃথক হয় তবে কোনও সমস্যা নেই। যদি একইরকম থাকে তবে আপনার জেনেরিক সংস্করণ থাকতে পারে যা গেটটাইপ () ব্যবহার করে টাইপের উপর ভিত্তি করে কিছু যুক্তি থাকতে পারে।
চার্লস গ্রাহাম 10
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.