এনাম বনাম স্ট্রংলি টাইপ করা এনুম


84

আমি সি ++ প্রোগ্রামিংয়ের একটি শিক্ষানবিস।

আজ আমি একটি নতুন বিষয় নিয়ে এসেছি: দৃ strongly়ভাবে টাইপ করা enum। আমি এটি কিছুটা গবেষণা করেছি কিন্তু এখন অবধি আমি কেন এটি আমাদের প্রয়োজন এবং এটির ব্যবহার কী তা খুঁজে বের করতে পারছি না?

উদাহরণস্বরূপ যদি আমাদের থাকে:

enum xyz{a, b, c};
/*a = 0, b = 1, c = 2, (Typical C format)*/

আমাদের কেন লিখতে হবে:

enum class xyz{a, b, c};

আমরা এখানে কি করার চেষ্টা করছি? আমার সবচেয়ে গুরুত্বপূর্ণ সন্দেহ এটি কীভাবে ব্যবহার করা যায়। আপনি কি একটি ছোট উদাহরণ প্রদান করতে পারেন, যা আমাকে বুঝতে সক্ষম করবে।

উত্তর:


114

ঠিক আছে, প্রথম উদাহরণ: পুরাতন স্টাইলের এনামগুলির নিজস্ব সুযোগ নেই:

enum Animals {Bear, Cat, Chicken};
enum Birds {Eagle, Duck, Chicken}; // error! Chicken has already been declared!

enum class Fruits { Apple, Pear, Orange };
enum class Colours { Blue, White, Orange }; // no problem!

দ্বিতীয়ত, তারা সুস্পষ্টভাবে অবিচ্ছেদ্য ধরণের রূপান্তর করে, যা অদ্ভুত আচরণের দিকে পরিচালিত করতে পারে:

bool b = Bear && Duck; // what?

অবশেষে, আপনি অন্তর্নিহিত ইন্টিগ্রাল টাইপ সি ++ 11 এনামগুলিকে নির্দিষ্ট করতে পারেন:

enum class Foo : char { A, B, C};

পূর্বে, অন্তর্নিহিত ধরণটি নির্দিষ্ট করা হয়নি, যা প্ল্যাটফর্মগুলির মধ্যে সামঞ্জস্যতার সমস্যা তৈরি করতে পারে। সম্পাদনা এটি মন্তব্যে নির্দেশ করা হয়েছে যে আপনি সি ++ 11 এ একটি "পুরানো শৈলী" এনুমের অন্তর্নিহিত ইন্টিগ্রাল টাইপও নির্দিষ্ট করতে পারেন।


আমাদের কি ঘোষণা / সংজ্ঞা দেওয়া দরকার enum class Coloursএবং enum class Fruits। কারন যখন আমি বনাম 2010 কোড লেখেন এটা একটি ত্রুটি ছোঁড়া "expects a defination or a tag name"অধীনে class
রাসমি রঞ্জন নায়ক

এছাড়াও: সি ++ 11 তে "সাধারণ" এনামের জন্য যেমন সি ++ 98 ডিফল্ট অন্তর্নিহিত ধরণের সংজ্ঞায়িত করা হয় না
বুড়িউজ

4
এছাড়াও: আপনি অন্তর্নিহিত প্রকারটি নির্দিষ্ট করে নিলে এনাম-এর ফরোয়ার্ড ঘোষণা করতে পারেন। সি ++ 11, সি ++ 98 এ সাধারণ এনামের জন্য এটি অনুমোদিত নয়। মাইক্রোসফ্ট সংকলক আপনাকে এনামের ফরওয়ার্ড ডিক্লোরেশন করার অনুমতি দেয়, তবে এটি কেবল এমএস এক্সটেনশান, এটি স্ট্যান্ডআর্ট নয় (উদাহরণস্বরূপ জিসিসি এটি অনুমোদন দেয় না) সুতরাং এখন এই জাতীয় জিনিস আইনী: এনওম ফরওয়ার্ড ডেক্লেয়ার: স্ট্যান্ড :: uint8_t;
বুড়িউজ

আমরা কী স্কোপড এনাম থাকতে পারি যা সুস্পষ্টভাবে একটি অবিচ্ছেদ্য ধরণের রূপান্তর করতে পারে?
এসএস অ্যান

4
@ এস এস এন না, অন্তর্নিহিত রূপান্তর বরং জোরালোভাবে টাইপ করা এনামের উদ্দেশ্যকে পরাস্ত করে। পরিবর্তে রূপান্তর সম্পাদন করতে একটি টেম্পলেট ফাংশন সংজ্ঞায়িত করুন; প্রকারটি নিষ্কাশন করতে std :: অন্তর্নিহিত_ টাইপ <T> :: টাইপ ব্যবহার করুন।
ডেভিড আর

17

এই আইবিএম পৃষ্ঠায় এনামগুলি সম্পর্কে একটি ভাল নিবন্ধ রয়েছে , এটি খুব বিস্তারিত এবং ভাল লেখা written সংক্ষেপে কয়েকটি গুরুত্বপূর্ণ বিষয় এখানে দেওয়া হল:

স্কোপড এনামগুলি নিয়মিত এনামগুলির দ্বারা সীমাবদ্ধতার বেশিরভাগ সমাধান করে: সম্পূর্ণ টাইপ সুরক্ষা, সুস্পষ্টভাবে সংজ্ঞায়িত অন্তর্নিহিত ধরণ, স্কোপ ইস্যু এবং সামনের ঘোষণা।

  • আপনি অন্যান্য ধরণের স্কোপযুক্ত এনামগুলির অন্তর্নিহিত রূপান্তরকে অস্বীকার করে প্রকারের সুরক্ষা পান।
  • আপনি একটি নতুন সুযোগ পেয়েছেন, এবং এনামগুলি আর কোনও সংলগ্ন সুযোগের মধ্যে নেই, নাম দ্বন্দ্ব থেকে নিজেকে বাঁচান।
  • স্কোপড এনামগুলি আপনাকে গণনার অন্তর্নিহিত ধরণের নির্দিষ্ট করার ক্ষমতা দেয় এবং স্কোপড এনামগুলির জন্য, যদি আপনি এটি নির্দিষ্ট না করে বেছে নেন তবে এটি পূর্বনির্ধারিত ডিফল্ট হয়।
  • একটি নির্দিষ্ট অন্তর্নিহিত টাইপ সহ যে কোনও এনাম এগিয়ে ঘোষণা করা যেতে পারে।

4
তৃতীয় এবং চতুর্থ পয়েন্টগুলি স্কোপযুক্ত গণনার জন্য নির্দিষ্ট নয়; আপনি কোনও গণনার অন্তর্নিহিত ধরণ নির্দিষ্ট করতে পারেন।
মাইক সিমুর

4
পিডিএফটির কম ভাঙা সংস্করণটির কোনও লিঙ্ক আছে? এতে থাকা কোডের উদাহরণগুলি আমার কোনও পিডিএফ দর্শনে রেন্ডার করে না, যা কল্পনাতে অনেকটাই ফেলে।
সারা সিনব্যাক

11

মানগুলি enum classপ্রকৃতপক্ষে প্রকারের enum class, underlying_typeসি-এনামগুলির মতো নয়।

enum xyz { a, b, c};
enum class xyz_c { d, f, e };

void f(xyz x)
{
}

void f_c(xyz_c x)
{
}

// OK.
f(0);
// OK for C++03 and C++11.
f(a);
// OK with C++11.
f(xyz::a);
// ERROR.
f_c(0);
// OK.
f_c(xyz_c::d);

5

এনাম ক্লাস ("নতুন enums", "শক্তিশালী enums") traditionalতিহ্যবাহী সি ++ গণনা সহ তিনটি সমস্যার সমাধান করে:

  1. প্রচলিতগুলি enumsস্পষ্টত রূপান্তরিত করে int, ত্রুটি সৃষ্টি করে যখন কেউ কোনও সংখ্যার পূর্ণসংখ্যা হিসাবে কাজ করতে চায় না।
  2. প্রচলিত enumsরেকর্ডগুলি তাদের গণকের আশেপাশের স্কোপে রফতানি করে যার ফলে নাম সংঘর্ষ হয়।
  3. অন্তর্নিহিত প্রকারটি enumনির্দিষ্ট করা যায় না, বিভ্রান্তি সৃষ্টি করে, সামঞ্জস্যের সমস্যা সৃষ্টি করে এবং সামনে ঘোষণা অসম্ভব করে তোলে।

enum class ("শক্তিশালী enums") দৃ strongly়ভাবে টাইপ করা এবং স্কোপযুক্ত:

enum Alert { green, yellow, orange, red }; // traditional enum

enum class Color { red, blue };   // scoped and strongly typed enum
                                  // no export of enumerator names into enclosing scope
                                  // no implicit conversion to int
enum class TrafficLight { red, yellow, green };

Alert a = 7;              // error (as ever in C++)
Color c = 7;              // error: no int->Color conversion

int a2 = red;             // ok: Alert->int conversion
int a3 = Alert::red;      // error in C++98; ok in C++11
int a4 = blue;            // error: blue not in scope
int a5 = Color::blue;     // error: not Color->int conversion

Color a6 = Color::blue;   // ok

যেমন দেখানো হয়েছে, traditionalতিহ্যবাহী এনামগুলি যথারীতি কাজ করে তবে আপনি এখন এনামের নামের সাথে বিকল্পভাবে যোগ্যতা অর্জন করতে পারেন।

নতুন এনামগুলি "এনাম ক্লাস" কারণ তারা traditionalতিহ্যবাহী গণনাগুলির (নামগুলির মান) দিকগুলি ক্লাসের দিকগুলি (স্কোপড সদস্য এবং রূপান্তরগুলির অনুপস্থিতি) এর সাথে একত্রিত করে।

অন্তর্নিহিত প্রকারটি নির্দিষ্ট করতে সক্ষম হওয়ায় সহজ আন্তঃব্যবহারযোগ্যতা এবং গণনাগুলির গ্যারান্টিযুক্ত আকারের মঞ্জুরি দেয়:

enum class Color : char { red, blue };  // compact representation

enum class TrafficLight { red, yellow, green };  // by default, the underlying type is int

enum E { E1 = 1, E2 = 2, Ebig = 0xFFFFFFF0U };   // how big is an E?
                                                 // (whatever the old rules say;
                                                 // i.e. "implementation defined")

enum EE : unsigned long { EE1 = 1, EE2 = 2, EEbig = 0xFFFFFFF0U };   // now we can be specific

এটি এনামগুলির অগ্রিম ঘোষণাও সক্ষম করে:

enum class Color_code : char;     // (forward) declaration
void foobar(Color_code* p);       // use of forward declaration
// ...
enum class Color_code : char { red, yellow, green, blue }; // definition

অন্তর্নিহিত প্রকারটি অবশ্যই স্বাক্ষরিত বা স্বাক্ষরবিহীন পূর্ণসংখ্যার ধরণের এক হতে হবে; ডিফল্ট হয় int

স্ট্যান্ডার্ড লাইব্রেরিতে, enumক্লাসগুলি এর জন্য ব্যবহৃত হয়:

  1. ম্যাপিং সিস্টেম নির্দিষ্ট ত্রুটি কোড: ইন <system_error>: enum class errc;
  2. পয়েন্টার সুরক্ষা সূচক: ইন <memory>:enum class pointer_safety { relaxed, preferred, strict };
  3. আই / ও স্ট্রিম ত্রুটি: ইন <iosfwd>:enum class io_errc { stream = 1 };
  4. অ্যাসিনক্রোনাস যোগাযোগের ত্রুটি পরিচালনা: এ <future>:enum class future_errc { broken_promise, future_already_retrieved, promise_already_satisfied };

এর মধ্যে বেশ কয়েকটিতে অপারেটর রয়েছে যেমন ==সংজ্ঞায়িত।


3

এনুম স্কোপ

গণনাগুলি তাদের গণকের আশেপাশের সুযোগে রফতানি করে। এটির দুটি ঘাটতি রয়েছে। প্রথমত, এটি নাম সংঘর্ষের দিকে নিয়ে যেতে পারে, যদি একই স্কোপে ঘোষণা করা বিভিন্ন এনামের দু'জন গণনার একই নাম থাকে; দ্বিতীয়ত, এনামের নাম সহ পুরোপুরি যোগ্যতাসম্পন্ন নাম সহ কোনও এনামুলেটর ব্যবহার করা সম্ভব নয়।

enum ESet {a0, a, a1, b1, c3};
enum EAlpha{a, b, c}

select = ESet::a; // error
select = a;       // is ambigious
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.