অ-টাইপ টেম্পলেট পরামিতি


93

আমি বুঝতে পারি যে নন-টাইপ টেম্পলেট প্যারামিটারটি একটি ধ্রুবক অবিচ্ছেদ্য অভিব্যক্তি হওয়া উচিত। কেউ আলোকপাত করতে পারে কেন এমন হয়?

template <std::string temp>
void foo()
{
     // ...
}
error C2993: 'std::string' : illegal type for non-type template parameter 'temp'.

ধ্রুবক অবিচ্ছেদ্য অভিব্যক্তি কী তা আমি বুঝতে পারি। std::stringউপরের স্নিপেটের মতো অ-ধ্রুবক ধরণের অনুমতি না দেওয়ার কারণ কী ?


17
একটি টেমপ্লেট পরামিতি সংকলন সময়ে সমাধান করা হয়।
এটিয়েন ডি মার্টেল

উত্তর:


122

আপনি এটি করতে না পারার কারণ হ'ল অ-ধ্রুবক এক্সপ্রেশনগুলি সংকলনের সময় পার্স এবং প্রতিস্থাপন করা যায় না। রানটাইমের সময় এগুলি পরিবর্তন করতে পারে, যার জন্য রানটাইম চলাকালীন একটি নতুন টেম্পলেট তৈরির প্রয়োজন হবে, যা সম্ভব নয় কারণ টেমপ্লেটগুলি একটি সংকলন-সময় ধারণা।

মানকটি নন-টাইপ টেম্পলেট প্যারামিটারগুলির জন্য কী অনুমতি দেয় তা এখানে (১৪.১ [টেম্পার্পারাম] পি ৪):

একটি অ-টাইপযুক্ত টেম্পলেট-প্যারামিটারের মধ্যে নিম্নলিখিতগুলির মধ্যে একটি (বিকল্পভাবে সিভি-কোয়ালিটিড) থাকতে পারে:

  • অবিচ্ছেদ্য বা গণনা প্রকার,
  • পয়েন্টার অব অবজেক্ট বা পয়েন্টার ফাংশন,
  • অবজেক্টের লভ্যালু রেফারেন্স বা ফাংশনের লভ্যালু রেফারেন্স,
  • সদস্য পয়েন্টার,
  • std::nullptr_t

6
@ ওলটওভারফ্লো: এটি "পয়েন্টার টু মেম্বার" এর আওতায় পড়ে। এটি হয় "সদস্য ফাংশনে পয়েন্টার" বা "সদস্য ডেটারে পয়েন্টার"।
জিও

4
এটি লক্ষণীয় যে অবজেক্টগুলিতে পয়েন্টারগুলির ক্ষেত্রে (বা উদাহরণ ক্ষেত্রগুলি), অবজেক্টগুলির অবশ্যই স্থিতিশীল স্টোরেজ সময়কাল এবং লিঙ্কেজ থাকতে হবে (বহিরাগত প্রাক সি ++ 11, সি ++ 11 এর অভ্যন্তরীণ বা বাহ্যিক) যাতে তাদের পয়েন্টারগুলি পারে সংকলন সময়ে তৈরি করা।
থিওডোর মুরডক

4
সি ++ ২০ এ এখন এই অনুমোদিত মঞ্জুরি দেওয়া হয়েছে যে প্রকারটির দৃ strong় কাঠামোগত সাম্য রয়েছে, আক্ষরিক, কোনও পরিবর্তনীয় / উদ্বায়ী সাবওবজেক্ট এবং যেখানে স্পেসশিপ অপারেটর সর্বজনীন।
Rakete1111

74

এটি অনুমোদিত নয়।

তবে এটি অনুমোদিত:

template <std::string * temp> //pointer to object
void f();

template <std::string & temp> //reference to object
void g();

সি ++ স্ট্যান্ডার্ড (2003) এ §14.1 / 6,7,8 দেখুন।


চিত্রণ:

template <std::string * temp> //pointer to object
void f()
{
   cout << *temp << endl;
}

template <std::string & temp> //reference to object
void g()
{
     cout << temp << endl;
     temp += "...appended some string";
}

std::string s; //must not be local as it must have external linkage!

int main() {
        s = "can assign values locally";
        f<&s>();
        g<s>();
        cout << s << endl;
        return 0;
}

আউটপুট:

can assign values locally
can assign values locally
can assign values locally...appended some string

7
@ মাহেশ: কারণ টেম্পলেটটি মূলত যা টেম্পলেটগুলিতে তা সেই std::stringপয়েন্টার বা রেফারেন্স অবজেক্টের ঠিকানা। যদি সেই ভেরিয়েবল স্থানীয় হয়, তবে ফাংশনটি যখনই ডাকা হবে তখন আপনি সম্ভবত বিভিন্ন ঠিকানা পাবেন would
জিও

11
@ মাহেশ: সংকলনের সময় আপনি জানেন না যে কল-স্ট্যাকটি কেমন দেখাচ্ছে। আপনার ক্রিয়াকলাপের আগে, সেখানে 10 অন্যান্য বা 3 জন বা অন্য অনেককে কল করা যেতে পারে, সুতরাং স্ট্যাকের ঠিকানা, যেখানে স্ট্রিংটি তৈরি হয় তা কল থেকে কলটিতে পরিবর্তিত হতে পারে। আপনার যখন বাহ্যিক সংযোগের সাথে কোনও অবজেক্ট থাকে, তখন ঠিকানাটি সংকলন / লিঙ্কেজের সময় স্থির করা হয়।
জিও

4
@ শিও " এর ঠিকানাটি সংকলন / সংযোগের সময় স্থির করা হয়েছে Or" না, স্থানান্তরযোগ্য বা অবস্থান-স্বতন্ত্র কোডের জন্য।
কৌতূহলী

4
এই উত্তরটি (বর্তমানে) ওপি-র প্রশ্নকে সম্বোধন করছে বলে মনে হচ্ছে না, যা জিজ্ঞাসা করেছিল যে এই আচরণটি কেন বিদ্যমান; এই উত্তরটি কোনও ব্যাখ্যা না দিয়ে কেবল ওপি-র উদাহরণ পুনরুদ্ধার করে।
কুক্সপ্লসোন

4
আমি পার্টির জন্য দেরি করেছি, মনে হচ্ছে স্মার্ট পয়েন্টারগুলিও কাজ করে না
নিকোলাস হামফ্রে

28

আপনি টেমপ্লেট আর্গুমেন্ট ম্যাঙ্গাল করতে সক্ষম হতে হবে

template <std::string temp>
void f() {
 // ...
}

f<"foo">();
f<"bar">(); // different function!?

এখন একটি ইমপল্টটির প্রয়োজন হয় কোনও std::stringবা এর জন্য, অন্য কোনও স্বেচ্ছাসেবক ব্যবহারকারী সংজ্ঞায়িত শ্রেণীর জন্য নির্দিষ্ট অক্ষরের এক অনন্য ধারা নিয়ে আসা দরকার , যার অর্থ প্রয়োগের জন্য জানা যায় না। এবং তদতিরিক্ত, স্বেচ্ছাসেবী শ্রেণীর অবজেক্টের মান সংকলন সময়ে গণনা করা যায় না।

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


10

একটি টেম্পলেট আর্গুমেন্ট তালিকার মধ্যে প্রদত্ত একটি অ-টাইপ টেম্পলেট আর্গুমেন্ট এমন একটি অভিব্যক্তি যা এর মানটি সংকলন সময়ে নির্ধারণ করা যেতে পারে। এই জাতীয় যুক্তি অবশ্যই হওয়া উচিত:

ধ্রুবক অভিব্যক্তি, বাহ্যিক সংযোগ সহ ফাংশন বা বস্তুর ঠিকানা বা স্থিত শ্রেণীর সদস্যদের ঠিকানা।

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


আপনি একটি উদ্ধৃতি ব্যবহার করেছেন, তবে উত্সটি কী? আমি যদি তা উদ্ধৃত করতে চাই তবে এটি উত্সাহিত করতে চাই।
গ্যাব্রিয়েল স্ট্যাপলস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.