সি ++ এনামগুলি স্বাক্ষরিত বা স্বাক্ষরবিহীন? এবং এক্সটেনশনের মাধ্যমে কোনও ইনপুটটি <= আপনার সর্বোচ্চ মান, এবং আপনার ন্যূনতম মানটি (আপনি 0 থেকে শুরু করেছেন এবং 1 দ্বারা বর্ধিত) ধরে রেখেছেন কিনা তা পরীক্ষা করে কোনও বৈধতা পরীক্ষা করা নিরাপদ?
সি ++ এনামগুলি স্বাক্ষরিত বা স্বাক্ষরবিহীন? এবং এক্সটেনশনের মাধ্যমে কোনও ইনপুটটি <= আপনার সর্বোচ্চ মান, এবং আপনার ন্যূনতম মানটি (আপনি 0 থেকে শুরু করেছেন এবং 1 দ্বারা বর্ধিত) ধরে রেখেছেন কিনা তা পরীক্ষা করে কোনও বৈধতা পরীক্ষা করা নিরাপদ?
উত্তর:
আপনার কোনও নির্দিষ্ট উপস্থাপনার উপর নির্ভর করা উচিত নয়। নীচের লিঙ্কটি পড়ুন । এছাড়াও, মানকটি বলে যে এটি বাস্তবায়ন-সংজ্ঞায়িত যা কোন এনামের জন্য অন্তর্নিহিত প্রকার হিসাবে ইন্টিগ্রাল টাইপ ব্যবহৃত হয়, ব্যতীত এটি ইন্টের চেয়ে বড় হবে না, যদি না কোনও মান অন্তর্নিহিত বা স্বাক্ষরবিহীন কোনও ইন্টিতে ফিট না করে।
সংক্ষেপে: আপনি স্বাক্ষরিত বা স্বাক্ষরিত কোনও এনামের উপর নির্ভর করতে পারবেন না।
উত্স যেতে যাক। এখানে সি ++ 03 স্ট্যান্ডার্ড (আইএসও / আইইসি 14882: 2003) নথিটি কি 7.2-5 (গণনার ঘোষণা) তে বলেছে:
একটি গণনার অন্তর্নিহিত ধরণ হল একটি অবিচ্ছেদ্য প্রকার যা গণনাতে সংজ্ঞায়িত সমস্ত গণকের মানকে উপস্থাপন করতে পারে। এটি রূপায়ণ-সংজ্ঞায়িত যা কোন সংখ্যার জন্য অন্তর্নিহিত প্রকারটি অন্তর্নিহিত প্রকার হিসাবে ব্যবহৃত হয় তা বাদে অন্তর্নিহিত প্রকারটি ইন্টের চেয়ে বড় হবে না যদি না কোনও এনুম্যরেটারের মান কোনও ইন্ট বা স্বাক্ষরযুক্ত ইনতে ফিট না করে।
সংক্ষেপে, আপনার সংকলকটি চয়ন করতে পারে (স্পষ্টতই, যদি আপনার কিছু গণনা মানের জন্য নেতিবাচক সংখ্যা থাকে তবে তা স্বাক্ষরিত হবে)।
আপনি স্বাক্ষরিত বা স্বাক্ষরিত হওয়ার উপর নির্ভর করবেন না। আপনি যদি তাদের সুস্পষ্টভাবে স্বাক্ষরিত বা স্বাক্ষরবিহীন করতে চান তবে আপনি নিম্নলিখিতটি ব্যবহার করতে পারেন:
enum X : signed int { ... }; // signed enum
enum Y : unsigned int { ... }; // unsigned enum
আপনি স্বাক্ষরিত বা স্বাক্ষরিত না হয়ে এটির উপর নির্ভর করবেন না। মান অনুযায়ী এটি বাস্তবায়ন-সংজ্ঞায়িত যা কোন এনামের জন্য অন্তর্নিহিত ধরণ হিসাবে ইন্টিগ্রাল টাইপ ব্যবহৃত হয়। যদিও বেশিরভাগ বাস্তবায়নে এটি একটি স্বাক্ষরিত পূর্ণসংখ্যা।
সি ++ 0 এক্সে দৃ strongly ়ভাবে টাইপযুক্ত গণনা যুক্ত করা হবে যা আপনাকে এনুমের ধরণ নির্দিষ্ট করার অনুমতি দেয়:
enum X : signed int { ... }; // signed enum
enum Y : unsigned int { ... }; // unsigned enum
এখনও, যদিও, এনামকে ভেরিয়েবল বা প্যারামিটারের ধরণের মতো ব্যবহার করে কিছু সাধারণ বৈধতা পাওয়া যায়:
enum Fruit { Apple, Banana };
enum Fruit fruitVariable = Banana; // Okay, Banana is a member of the Fruit enum
fruitVariable = 1; // Error, 1 is not a member of enum Fruit
// even though it has the same value as banana.
সংকলক এনামস স্বাক্ষরিত বা স্বাক্ষরবিহীন কিনা তা সিদ্ধান্ত নিতে পারে।
এনামগুলিকে বৈধতা দেওয়ার আরেকটি পদ্ধতি হ'ল এনামকে ভেরিয়েবল টাইপ হিসাবে ব্যবহার করা। উদাহরণ স্বরূপ:
enum Fruit
{
Apple = 0,
Banana,
Pineapple,
Orange,
Kumquat
};
enum Fruit fruitVariable = Banana; // Okay, Banana is a member of the Fruit enum
fruitVariable = 1; // Error, 1 is not a member of enum Fruit even though it has the same value as banana.
এমনকি কিছু পুরানো উত্তর 44 টি আপত্তি পেয়েছে, আমি সেগুলির সাথে একমত নই। সংক্ষেপে, আমি মনে করি না underlying type
আমাদের এনামগুলির যত্ন নেওয়া উচিত ।
প্রথমে, সি ++ 03 এনাম টাইপ স্বতন্ত্র ধরণের যা স্বাক্ষরের কোনও ধারণা নেই। যেহেতু সি ++ 03 স্ট্যান্ডার্ড থেকেdcl.enum
7.2 Enumeration declarations
5 Each enumeration defines a type that is different from all other types....
সুতরাং যখন আমরা একটি এনাম টাইপের চিহ্নের কথা বলছি, <
অপারেটরটি ব্যবহার করে 2 এনাম অপারেন্ডের তুলনা করার সময় বলুন , আমরা প্রকৃতপক্ষে এনাম টাইপকে কিছু অবিচ্ছেদ্য ধরণের রূপান্তরিত করার বিষয়ে কথা বলছি। এটি গুরুত্বপূর্ণ এই ইন্টিগ্রাল টাইপের চিহ্ন । এবং এনামকে অবিচ্ছেদ্য প্রকারে রূপান্তর করার সময়, এই বিবৃতিটি প্রযোজ্য:
9 The value of an enumerator or an object of an enumeration type is converted to an integer by integral promotion (4.5).
এবং দৃশ্যত, এনামের অন্তর্নিহিত ধরণের ইন্টিগ্রাল প্রচারের সাথে কিছুই করার নেই to যেহেতু স্ট্যান্ডার্ডটি ইন্টিগ্রাল প্রচারকে এভাবে সংজ্ঞায়িত করে:
4.5 Integral promotions conv.prom
.. An rvalue of an enumeration type (7.2) can be converted to an rvalue of the first of the following types that can represent all the values of the enumeration
(i.e. the values in the range bmin to bmax as described in 7.2: int, unsigned int, long, or unsigned long.
সুতরাং, একটি enum টাইপ হয়ে কিনা signed int
বা unsigned int
কিনা উপর নির্ভর করে signed int
সংজ্ঞায়িত তথ্যসংগ্রহকারী না enum অন্তর্নিহিত ধরনের সমস্ত মান থাকতে পারে।
আমার সম্পর্কিত প্রশ্নটি সি ++ এনাম প্রকারের ইন্টিগ্রাল প্রকারে রূপান্তরিত করার পরে ভুলের সাইন ইন দেখুন
-Wsign-conversion
। আমরা আমাদের কোডে অনিচ্ছাকৃত ভুল ধরতে সহায়তা করতে এটি ব্যবহার করি। তবে +1 স্ট্যান্ডার্ড উদ্ধৃত করার জন্য, এবং একটি এনাম এর সাথে কোনও প্রকার ( signed
বনাম unsigned
) জড়িত তা নির্দেশ করে।
ভবিষ্যতে, C ++ 0x এর সাথে দৃ strongly ়ভাবে টাইপ করা গণনাগুলি উপলব্ধ হবে এবং এর বেশ কয়েকটি সুবিধা রয়েছে (যেমন টাইপ-সুরক্ষা, স্পষ্টত অন্তর্নিহিত ধরণের বা স্পষ্টত স্কোপিং)। এটির সাথে আপনি ধরণের সাইন সম্পর্কে আরও ভালভাবে নিশ্চিত হতে পারেন।
স্বাক্ষরিত / স্বাক্ষরবিহীন সম্পর্কে অন্যরা ইতিমধ্যে যা বলেছে তা ছাড়াও, একটি গণিতের প্রকারের পরিধি সম্পর্কে স্ট্যান্ডার্ড যা বলেছে তা এখানে:
.2.২ ()): "একটি গণনার জন্য যেখানে ই (মিনিট) হ'ল ক্ষুদ্রতম গণক এবং ই (সর্বাধিক) বৃহত্তম, গণনার মানগুলি বি (ন্যূনতম) থেকে বি (সর্বাধিক) সীমাতে অন্তর্নিহিত ধরণের মান হয় ), যেখানে খ (মিনিট) এবং বি (সর্বোচ্চ) যথাক্রমে, ক্ষুদ্রতম বিটফিল্ডের সবচেয়ে ছোট এবং বৃহত্তম মান যা ই (মিনিট) এবং ই (সর্বাধিক) সঞ্চয় করতে পারে। এমন একটি সংখ্যার সংজ্ঞা দেওয়া সম্ভব যা মানগুলি সংজ্ঞায়িত না করে এর যে কোনও গণক দ্বারা "
উদাহরণস্বরূপ:
enum { A = 1, B = 4};
একটি গণিত প্রকার নির্ধারণ করে যেখানে e (সর্বনিম্ন) 1 এবং e (সর্বাধিক) 4 হয়। যদি অন্তর্নিহিত প্রকারটি স্বাক্ষরিত হয় তবে সর্বনিম্ন প্রয়োজনীয় বিটফিল্ডে 4 বিট থাকে এবং যদি আপনার প্রয়োগের ints দুটি সংখ্যক পরিপূরক হয় তবে এর বৈধ পরিসীমা এনামটি -8 থেকে 7. এর মধ্যে অন্তর্নিহিত প্রকারটি স্বাক্ষরিত না হলে এটিতে 3 টি বিট থাকে এবং পরিসীমা 0 থেকে 7 থাকে you যদি যত্নশীল হন তবে আপনার সংকলক ডকুমেন্টেশন পরীক্ষা করুন (উদাহরণস্বরূপ আপনি যদি গণকের পরিবর্তে ইন্টিগ্রাল মানগুলি কাস্ট করতে চান তবে অঙ্কিত প্রকার, তারপরে আপনাকে জানতে হবে যে মানটি গণনার পরিসরে রয়েছে কিনা - ফলাফলের এনাম মানটি অনির্ধারিত না থাকলে)।
সেই মানগুলি আপনার ফাংশনে বৈধ ইনপুট কিনা তা গণিত প্রকারের বৈধ মান কিনা তা থেকে আলাদা সমস্যা হতে পারে। আপনার চেকিং কোডটি সম্ভবত পরবর্তীকালের চেয়ে পূর্বের সম্পর্কে উদ্বিগ্ন এবং তাই এই উদাহরণে কমপক্ষে> = এ এবং <= বি পরীক্ষা করা উচিত।
এটিকে std::is_signed<std::underlying_type
+ স্কোপড এনামগুলি ডিফল্ট হিসাবে পরীক্ষা করে দেখুনint
https://en.cppreferences.com/w/cpp/language/enum বোঝায়:
main.cpp
#include <cassert>
#include <iostream>
#include <type_traits>
enum Unscoped {};
enum class ScopedDefault {};
enum class ScopedExplicit : long {};
int main() {
// Implementation defined, let's find out.
std::cout << std::is_signed<std::underlying_type<Unscoped>>() << std::endl;
// Guaranteed. Scoped defaults to int.
assert((std::is_same<std::underlying_type<ScopedDefault>::type, int>()));
// Guaranteed. We set it ourselves.
assert((std::is_same<std::underlying_type<ScopedExplicit>::type, long>()));
}
সংকলন এবং চালান:
g++ -std=c++17 -Wall -Wextra -pedantic-errors -o main main.cpp
./main
আউটপুট:
0
উবুন্টু 16.04, জিসিসি 6.4.0 এ পরীক্ষিত।