টেমপ্লেট প্যারামিটারের ধরণ কীভাবে পরীক্ষা করবেন?


97

ধরুন আমার একটি টেম্পলেট ফাংশন এবং দুটি ক্লাস রয়েছে

class animal {
}
class person {
}

template<class T>
void foo() {
  if (T is animal) {
    kill();
  }
}

আমি কীভাবে টি এর চেক করব তা প্রাণী? আমি রান সময় সময় যাচাই করে এমন কিছু পেতে চাই না। ধন্যবাদ


62
আমি "কিল" এর পরিবর্তে "পোষা প্রাণী"
রেখে দিতাম

উত্তর:


135

ব্যবহার is_same:

#include <type_traits>

template <typename T>
void foo()
{
    if (std::is_same<T, animal>::value) { /* ... */ }  // optimizable...
}

সাধারণত, এটি সম্পূর্ণ অকার্যকর নকশা, যদিও এবং আপনি সত্যই বিশেষজ্ঞ করতে চান :

template <typename T> void foo() { /* generic implementation  */ }

template <> void foo<animal>()   { /* specific for T = animal */ }

এও লক্ষ্য করুন যে স্পষ্টত (অ-অনুমিত) যুক্তিযুক্ত ফাংশন টেম্পলেটগুলি হওয়া অস্বাভাবিক। এটি শোনা যায় না, তবে প্রায়শই আরও ভাল পন্থা থাকে।


4
থ্যাঙ্কস! প্রকৃতপক্ষে তারা
প্রচুর

4
@ হোয়াট বিউটিফিউড ওয়ার্ল্ড: আপনি সর্বদা আপনার কোডটি ফ্যাক্ট করতে পারেন যাতে টাইপ-নির্ভর অংশটি একটি বিশেষায়িত ফাংশনে পুনর্নির্মাণ করা যায় ...
কেরেক এসবি

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

4
@ ওয়াটাবেইলিউটার ওয়ার্ল্ড: বৈশিষ্ট্য মানগুলি সমস্ত স্ট্যাটিকালি পরিচিত। কোনও রানটাইম ব্যয় হওয়া উচিত নয়, আপনার সংকলকটি অর্ধ-শালীন হয়। সন্দেহ থাকলেও অ্যাসেম্বলি পরীক্ষা করে দেখুন।
কেরেরেক এসবি

4
@ অ্যাড্রি.সি.এস .: যেহেতু ছাড় দেওয়া Tহয়নি, তাই আপনি করার মতো খুব বেশি কিছু নেই। আপনি প্রাথমিক টেম্পলেটটি অযৌক্তিকভাবে ছেড়ে দিতে পারেন এবং একটি বিশেষীকরণ তৈরি করতে পারেন, বা আপনি একটি স্ট্যাটিক প্রতিস্থাপন যুক্ত করতে পারেন is_same
কেরেক এসবি

38

আমার মনে হয় আজকের দিনগুলি ব্যবহার করা আরও ভাল তবে কেবল সি ++ 17 দিয়ে।

#include <type_traits>

template <typename T>
void foo() {
    if constexpr (std::is_same_v<T, animal>) {
        // use type specific operations... 
    } 
}

আপনি যদি কিছু প্রকারের নির্দিষ্ট ক্রিয়াকলাপগুলি ব্যবহার করেন তবে constexprএই কোডটি সংকলন করবে না expression


8
পরিবর্তে std::is_same<T, U>::valueআপনি খাটো ব্যবহার করতে পারেন:std::is_same_v<T, U>
ফিউরিশ

12

সি ++ 17 এ, আমরা রূপগুলি ব্যবহার করতে পারি ।

ব্যবহার করতে std::variant, আপনাকে শিরোনাম অন্তর্ভুক্ত করতে হবে:

#include <variant>

এর পরে, আপনি আপনার কোডটিতে এটি যুক্ত করতে পারেন std::variant:

using Type = std::variant<Animal, Person>;

template <class T>
void foo(Type type) {
    if (std::is_same_v<type, Animal>) {
        // Do stuff...
    } else {
        // Do stuff...
    }
}

8
টি এবং টাইপ কীভাবে সংযুক্ত রয়েছে?
mabraham

4
এই উত্তরটি বেশ কয়েকটি উপায়ে সমস্যাযুক্ত। প্রকৃত ত্রুটিগুলি ছাড়াও ( typeযা প্রকারের মান Typeবা কোনও টেম্পলেট যা এখানে is_same_vবোঝা যায় না ) এর প্রসঙ্গে অর্থবোধক নয় variant। সম্পর্কিত "বৈশিষ্ট্য" হয় holds_alternative
পিক্সেল কেমিস্ট

std::variantএখানে সম্পূর্ণ অপ্রয়োজনীয়
tjysdsg

7

আপনি তাদের টেমপ্লেটগুলিকে এই জাতীয় পরামিতিগুলিতে যা পেরেছে তার উপর ভিত্তি করে বিশেষায়িত করতে পারেন:

template <> void foo<animal> {

}

মনে রাখবেন যে এটি যে ধরণের পাস হয়েছে তার উপর ভিত্তি করে এটি সম্পূর্ণ নতুন ফাংশন তৈরি করে T। এটি সাধারনত পছন্দনীয় কারণ এটি বিশৃঙ্খলা হ্রাস করে এবং মূলত আমাদের টেমপ্লেটগুলি প্রথম স্থানে রাখে।


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

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