জেনেরিকগুলির বেশিরভাগ বাস্তবায়ন (বা বরং: প্যারামেট্রিক পলিমারফিজম) প্রকার ক্ষয়টি ব্যবহার করে। এটি জেনেরিক কোড সংকলনের সমস্যাটি ব্যাপকভাবে সরল করে, তবে কেবল বাক্সযুক্ত প্রকারের জন্যই কাজ করে: যেহেতু প্রতিটি যুক্তি কার্যকরীভাবে একটি অস্বচ্ছ পয়েন্টার, তাই আমাদের আর্গুমেন্টগুলিতে ক্রিয়াকলাপ করতে একটি ভিটিবেল বা অনুরূপ প্রেরণ প্রক্রিয়া দরকার। জাভাতে:
<T extends Addable> T add(T a, T b) { … }
সংকলন করা যায়, টাইপ-চেক করা যায় এবং একইভাবে বলা যেতে পারে
Addable add(Addable a, Addable b) { … }
জেনেরিকগুলি ব্যতীত কল সাইটে আরও তথ্যের সাথে টাইপ চেকার সরবরাহ করে। এই অতিরিক্ত তথ্য টাইপ ভেরিয়েবলগুলি দিয়ে পরিচালনা করা যায় , বিশেষত যখন জেনেরিক প্রকারগুলি অনুমান করা হয়। টাইপ চেকিংয়ের সময়, প্রতিটি জেনেরিক টাইপ একটি ভেরিয়েবলের সাথে প্রতিস্থাপন করা যেতে পারে, আসুন এটি কল করুন $T1
:
$T1 add($T1 a, $T1 b)
পরিবর্তনশীল টাইপটি ততক্ষণে পরিচিত হওয়ার সাথে সাথে আরও তথ্যগুলির সাথে আপডেট করা হয় যতক্ষণ না এটি কংক্রিটের ধরণের সাথে প্রতিস্থাপন করা যায়। টাইপ চেকিং অ্যালগরিদম এমনভাবে লিখতে হবে যা এই ধরণের ভেরিয়েবলগুলিকে পুরোপুরি এখনও সমাধান না করে এমনভাবে সামঞ্জস্য করে। জাভা নিজেই এটি সাধারণত সহজেই করা যায় যেহেতু প্রায়শই ফাংশন কলটির প্রকারটি জানা প্রয়োজন আগে যুক্তিগুলির ধরণটি প্রায়শই জানা যায়। একটি উল্লেখযোগ্য ব্যতিক্রম হ'ল ফাংশন আর্গুমেন্ট হিসাবে ল্যাম্বডা এক্সপ্রেশন, যা এই জাতীয় ধরণের ভেরিয়েবলগুলির প্রয়োজন।
অনেক পরে, একটি অপ্টিমাইজার নির্দিষ্ট যুক্তিগুলির জন্য বিশেষায়িত কোড তৈরি করতে পারে, এটি তখন কার্যকরভাবে এক ধরণের ইনলাইনিং হতে পারে।
জেনেরিক-টাইপযুক্ত আর্গুমেন্টগুলির জন্য একটি ভিটিবেল এড়ানো যায় যদি জেনেরিক ফাংশন টাইপটিতে কোনও ক্রিয়াকলাপ না চালায় তবে কেবল সেগুলি অন্য ফাংশনে প্রেরণ করে। যেমন হাস্কেল ফাংশনটিতে আর্গুমেন্টটি call :: (a -> b) -> a -> b; call f x = f x
বাক্স করতে হবে না x
। যাইহোক, এর জন্য একটি কলিং কনভেনশন দরকার যা তাদের আকারগুলি না জেনে মানগুলির মধ্য দিয়ে যেতে পারে, যা মূলত এটি কোনওভাবে পয়েন্টারে সীমাবদ্ধ করে।
এই ক্ষেত্রে বেশিরভাগ ভাষার থেকে সি ++ খুব আলাদা। একটি টেম্প্লেটেড ক্লাস বা ফাংশন (আমি কেবল এখানে টেম্পলেটযুক্ত ফাংশনগুলি নিয়ে আলোচনা করব) নিজে কল হয় না। পরিবর্তে, টেমপ্লেটগুলি একটি সংকলন-সময় মেটা-ফাংশন হিসাবে বোঝা উচিত যা কোনও আসল ফাংশন দেয়। এক মুহুর্তের জন্য টেমপ্লেট আর্গুমেন্ট অনুমান উপেক্ষা করে, সাধারণ পদ্ধতির পরে এই পদক্ষেপগুলিতে সিদ্ধ হয়:
প্রদত্ত টেমপ্লেট আর্গুমেন্টগুলিতে টেম্পলেটটি প্রয়োগ করুন। উদাহরণস্বরূপ কল template<class T> T add(T a, T b) { … }
করা add<int>(1, 2)
আমাদের আসল ফাংশন দেবে int __add__T_int(int a, int b)
(বা নাম-ম্যাঙ্গলিংয়ের যে কোনও পদ্ধতিই ব্যবহৃত হয়)।
যদি এই ক্রিয়াকলাপের কোডটি ইতিমধ্যে বর্তমান সংকলন ইউনিটে উত্পন্ন হয়েছে, চালিয়ে যান। অন্যথায়, কোডটি তৈরি করুন যেন কোনও int __add__T_int(int a, int b) { … }
উত্স কোডটিতে কোনও ফাংশন লেখা হয়েছিল। এটিতে টেমপ্লেট যুক্তির সমস্ত উপস্থিতি এর মানগুলির সাথে প্রতিস্থাপন জড়িত। এটি সম্ভবত একটি এএসটি-এএসটি রূপান্তর। তারপরে, উত্পন্ন এএসটি-তে টাইপ চেকিং সম্পাদন করুন।
কলটি কম্পাইল করুন যেন উত্স কোডটি ছিল __add__T_int(1, 2)
।
নোট করুন যে সি ++ টেম্পলেটগুলির ওভারলোড রেজোলিউশন ব্যবস্থার সাথে একটি জটিল ইন্টারঅ্যাকশন রয়েছে, যা আমি এখানে বর্ণনা করতে চাই না। এছাড়াও মনে রাখবেন যে এই কোড-জেনারেশনটি একটি ভার্চুয়াল এমন একটি টেম্প্লেটেড পদ্ধতি থাকা অসম্ভব করে তোলে - একটি টাইপ-ইরেজর ভিত্তিক পদ্ধতির এই যথেষ্ট বাধা থেকে ভোগ হয় না।
আপনার সংকলক এবং / অথবা ভাষার জন্য এর অর্থ কী? আপনি যে ধরণের জেনেরিক অফার করতে চান সে সম্পর্কে আপনাকে সাবধানে চিন্তা করতে হবে। টাইপ অনুমানের অনুপস্থিতিতে প্রকার মুছে ফেলা হ'ল যদি আপনি বাক্সযুক্ত প্রকারকে সমর্থন করেন তবে সবচেয়ে সহজ সম্ভাবনা approach টেমপ্লেট বিশেষায়িতকরণটি মোটামুটি সহজ বলে মনে হয় তবে নাম ম্যাগলিং এবং (একাধিক সংকলন ইউনিটের জন্য) আউটপুটে যথেষ্ট নকল জড়িত, যেহেতু টেমপ্লেটগুলি কল সাইটে ইনস্ট্যান্ট হয়, সংজ্ঞা সাইট নয়।
আপনি যে অ্যাপ্রোচটি দেখিয়েছেন তা হ'ল মূলত একটি সি ++ - টেম্পলেট পদ্ধতির মতো। তবে, আপনি বিশেষায়িত / ইনস্ট্যান্টিয়েটেড টেম্পলেটগুলি মূল টেমপ্লেটের "সংস্করণ" হিসাবে সঞ্চয় করেন। এটি বিভ্রান্তিকর: এগুলি ধারণাগতভাবে একই নয় এবং কোনও ফাংশনের বিভিন্ন তাত্ক্ষণিকভাবে বন্যভাবে বিভিন্ন ধরণের থাকতে পারে। আপনি যদি ফাংশন ওভারলোডিংকেও অনুমতি দেন তবে এটি দীর্ঘ সময়ের বিষয়গুলিকে জটিল করবে। পরিবর্তে, আপনার একটি ওভারলোড সেটের একটি ধারণা দরকার যাতে একটি নাম ভাগ করে নেওয়ার সমস্ত সম্ভাব্য ফাংশন এবং টেম্পলেট রয়েছে। অতিরিক্ত লোডিং সমাধানের জন্য ব্যতীত, আপনি বিভিন্ন তাত্ক্ষণিক টেম্পলেট একে অপরের থেকে সম্পূর্ণ আলাদা বিবেচনা করতে পারেন।