নিম্নলিখিত সংজ্ঞাগুলির মধ্যে কোনও পার্থক্য আছে?
const double PI = 3.141592653589793;
constexpr double PI = 3.141592653589793;
যদি তা না হয় তবে C ++ 11 এ কোন স্টাইলটি পছন্দ করা হচ্ছে?
নিম্নলিখিত সংজ্ঞাগুলির মধ্যে কোনও পার্থক্য আছে?
const double PI = 3.141592653589793;
constexpr double PI = 3.141592653589793;
যদি তা না হয় তবে C ++ 11 এ কোন স্টাইলটি পছন্দ করা হচ্ছে?
উত্তর:
আমি বিশ্বাস করি একটি পার্থক্য আছে। আসুন তাদের নামকরণ করুন যাতে আমরা তাদের সম্পর্কে আরও সহজে কথা বলতে পারি:
const double PI1 = 3.141592653589793;
constexpr double PI2 = 3.141592653589793;
উভয় PI1
এবং PI2
ধ্রুবক, যার অর্থ আপনি এগুলি সংশোধন করতে পারবেন না। তবে কেবল PI2
একটি সংকলন-সময় ধ্রুবক। এটা তোলে হইবে কম্পাইল সময়ে সক্রিয়া করা হবে। PI1
সংকলন সময় বা রান সময় সূচনা হতে পারে। তদুপরি, কেবল PI2
এমন একটি প্রসঙ্গে ব্যবহার করা যেতে পারে যার জন্য একটি সংকলন-সময় ধ্রুবক প্রয়োজন। উদাহরণ স্বরূপ:
constexpr double PI3 = PI1; // error
কিন্তু:
constexpr double PI3 = PI2; // ok
এবং:
static_assert(PI1 == 3.141592653589793, ""); // error
কিন্তু:
static_assert(PI2 == 3.141592653589793, ""); // ok
আপনার কোনটি ব্যবহার করা উচিত? আপনার প্রয়োজন মেলে যা ব্যবহার করুন। আপনি কি নিশ্চিত করতে চান যে আপনার কাছে একটি সংকলিত সময় ধ্রুবক রয়েছে যা প্রসঙ্গে যেগুলি একটি সংকলন-সময় ধ্রুবক প্রয়োজন সেখানে ব্যবহার করা যেতে পারে? আপনি কি রান সময়তে গণনার সাথে এটি আরম্ভ করতে সক্ষম হতে চান? প্রভৃতি
const int N = 10; char a[N];
কাজ করে এবং অ্যারে সীমা অবশ্যই সংকলন-সময় ধ্রুবক হতে হবে।
PI1
অ্যারে ব্যবহারের জন্য একটি সংকলন-কাল অবিচ্ছেদ্য ধ্রুবক হিসাবে রূপান্তর করতে দেয়, তবে অ-টাইপ অবিচ্ছেদ্য টেম্পলেট প্যারামিটার হিসাবে ব্যবহারের জন্য নয়। সুতরাং PI1
একটি অবিচ্ছেদ্য টাইপের সংকলন-সময় রূপান্তরকরণটি কিছুটা হিট মনে হয় এবং আমাকে মিস করে।
enum
ইনিশিয়ালাইজার হিসাবে ব্যবহার হ'ল const
এবং constexpr
(এবং উভয়ই double
কোনওভাবেই কাজ করে না) মধ্যে কেবল দুটি উল্লেখযোগ্য পার্থক্য ।
1 / PI1
এবং 1 / PI2
বিভিন্ন ফলাফল হতে পারে। আমি মনে করি না এই কারিগরিটি অবশ্য এই উত্তরের পরামর্শের মতো গুরুত্বপূর্ণ।
constexpr double PI3 = PI1;
আমার জন্য সঠিকভাবে কাজ করে। (এমএসভিএস ২০১৩ সিটিপি)। আমি কি ভুল করছি?
এখানে কোনও পার্থক্য নেই, তবে এটি আপনার কাছে কনস্ট্রাক্টর রয়েছে এমন টাইপ করার ক্ষেত্রে গুরুত্বপূর্ণ।
struct S {
constexpr S(int);
};
const S s0(0);
constexpr S s1(1);
s0
এটি একটি ধ্রুবক, তবে এটি সংকলন-সময় আরম্ভ করার প্রতিশ্রুতি দেয় না। s1
চিহ্নিত করা হয়েছে constexpr
, সুতরাং এটি একটি ধ্রুবক এবং কারণ S
এর নির্মাণকারীকে চিহ্নিত করা হয়েছে constexpr
, এটি সংকলন-সময় শুরু করা হবে।
বেশিরভাগ ক্ষেত্রে এটি যখন রানটাইমের সূচনাটি সময়সাপেক্ষ হতে পারে এবং আপনি সেই কাজটি সংকলকটির দিকে ধাক্কা দিতে চান, যেখানে এটি সময়সাপেক্ষও বটে, তবে সংকলিত প্রোগ্রামটির প্রয়োগের সময়টি ধীর করে দেয় না
constexpr
বস্তুর সংকলন-সময় গণনা অসম্ভব হয়ে উঠলে এটি রোগ নির্ণয়ের দিকে নিয়ে যায়। কম স্পষ্টত কি ধরণের পরামিতি প্রত্যাশা একটি ফাংশন সংকলন সময়ে সঞ্চালিত হতে পারে কিনা প্যারামিটার হিসাবে ঘোষিত করা উচিত const
এবং না constexpr
: যেমন, constexpr int foo(S)
আমি কল করলে সংকলন সময়ে কার্যকর করা হবে foo(s0)
?
foo(s0)
সংকলন-সময়ে মৃত্যুদন্ড কার্যকর করা হবে কিনা তা নিয়ে আমার সন্দেহ , তবে আপনি কখনই জানেন না: একটি সংকলককে এই ধরনের অপ্টিমাইজেশন করার অনুমতি দেওয়া হয়েছে। অবশ্যই, জিসিসি 4.7.2 বা ঝাঁকুনি না 3.2 আমাকে সংকলন করতে দেয়constexpr a = foo(s0);
কনসেক্সেক্স এমন একটি মান নির্দেশ করে যা সংকলনের সময় ধ্রুবক এবং পরিচিত।
কনস্ট একটি মানকে নির্দেশ করে যা কেবল ধ্রুবক; সংকলনের সময় জানতে বাধ্যতামূলক নয়।
int sz;
constexpr auto arraySize1 = sz; // error! sz's value unknown at compilation
std::array<int, sz> data1; // error! same problem
constexpr auto arraySize2 = 10; // fine, 10 is a compile-time constant
std::array<int, arraySize2> data2; // fine, arraySize2 is constexpr
নোট করুন কনস্টেক্সপ্রের মতো একই গ্যারান্টি সরবরাহ করে না, কারণ সংকলনের সময় পরিচিত মানগুলির সাথে কনস্ট অবজেক্টগুলি আরম্ভ করার দরকার নেই।
int sz;
const auto arraySize = sz; // fine, arraySize is const copy of sz
std::array<int, arraySize> data; // error! arraySize's value unknown at compilation
সমস্ত কনটেক্সট্রপ অবজেক্ট কনস্ট, তবে সমস্ত কনস্টেক্স প্রজেক্ট কনস্টেক্সপ্র নয়।
আপনি যদি কম্পাইলারদের গ্যারান্টি দিতে চান যে কোনও ভেরিয়েবলের একটি মান রয়েছে যা সংকলন-সময় ধ্রুবকগুলির প্রয়োজনে প্রসঙ্গে ব্যবহার করা যেতে পারে, তবে পৌঁছানোর সরঞ্জামটি কনটেক্সট্রপ, কনস্টেক্সার নয়।
একটি কনটেক্সপ্রস সিম্বলিক ধ্রুবককে অবশ্যই একটি মান দিতে হবে যা সংকলনের সময় জ্ঞাত। উদাহরণ স্বরূপ:
constexpr int max = 100;
void use(int n)
{
constexpr int c1 = max+7; // OK: c1 is 107
constexpr int c2 = n+7; // Error: we don’t know the value of c2
// ...
}
কেসগুলি পরিচালনা করতে যেখানে একটি "ভেরিয়েবল" এর মান যে একটি মান দিয়ে আরম্ভ করা হয় যা সংকলন সময়ে জানা যায় না তবে আরম্ভের পরে কখনই পরিবর্তন হয় না, সি ++ ধ্রুবকের দ্বিতীয় রূপ দেয় (একটি কনস্ট )। উদাহরণ স্বরূপ:
constexpr int max = 100;
void use(int n)
{
constexpr int c1 = max+7; // OK: c1 is 107
const int c2 = n+7; // OK, but don’t try to change the value of c2
// ...
c2 = 7; // error: c2 is a const
}
এই ধরনের " কনস্ট ভেরিয়েবল" দুটি কারণে খুব সাধারণ:
রেফারেন্স: "প্রোগ্রামিং: সি ++ ব্যবহার করে নীতিমালা এবং অনুশীলন" স্ট্রস্ট্রপ দ্বারা