সি ++ সংকলক কেন অপারেটর == এবং অপারেটরকে সংজ্ঞায়িত করবেন না! =?


302

সংকলকটি আপনার পক্ষে যথাসম্ভব কাজ করতে দেওয়ার আমি একটি বড় অনুরাগী। সাধারণ ক্লাস লেখার সময় সংকলক আপনাকে 'ফ্রি' এর জন্য নিম্নলিখিতটি দিতে পারে:

  • একটি ডিফল্ট (খালি) নির্মাণকারী
  • একটি অনুলিপি নির্মাণকারী
  • একজন ধ্বংসকারী
  • একটি অ্যাসাইনমেন্ট অপারেটর ( operator=)

তবে এটি আপনাকে কোনও তুলনামূলক অপারেটর দেওয়ার মতো বলে মনে হচ্ছে না - যেমন operator==বা operator!=। উদাহরণ স্বরূপ:

class foo
{
public:
    std::string str_;
    int n_;
};

foo f1;        // Works
foo f2(f1);    // Works
foo f3;
f3 = f2;       // Works

if (f3 == f2)  // Fails
{ }

if (f3 != f2)  // Fails
{ }

এর কি কোনও ভাল কারণ আছে? সদস্য দ্বারা সদস্যের তুলনা করা কেন সমস্যা হবে? স্পষ্টতই যদি শ্রেণি মেমরি বরাদ্দ করে তবে আপনি যত্নবান হতে চান, তবে একটি সাধারণ শ্রেণির জন্য অবশ্যই সংকলক আপনার জন্য এটি করতে পারে?


4
অবশ্যই, ডেস্ট্রাক্টর বিনামূল্যে প্রদান করা হয়।
জোহান জেরেল

23
তার সাম্প্রতিক এক আলোচনায় অ্যালেক্স স্টেপানোভ উল্লেখ করেছিলেন যে কোনও শর্তের ==মধ্যে একটি ডিফল্ট স্বয়ংক্রিয় অ্যাসাইনমেন্ট ( =) রয়েছে তেমনিভাবে ডিফল্ট স্বয়ংক্রিয় না হওয়াও ভুল ছিল । (পয়েন্টারগুলি সম্পর্কে যুক্তিটি অসঙ্গত কারণ যুক্তিটি কেবল দ্বিতীয়টির জন্য নয় =এবং উভয় ক্ষেত্রেই প্রযোজ্য ==)।
alfC

2
@becko এটা A9 এ সিরিজে এগুলির মধ্যে একটি: youtube.com/watch?v=k-meLQaYP5Y , আমি মনে করতে পারছি না আলোচনা যা। এমন একটি প্রস্তাবও রয়েছে যে এটি সি ++ 17 ওপেন -স্টডি.আর
জেটিসি

1
@ বেকো, এটি ইউটিউবে উপলব্ধ, এ 9 তে "উপাদানগুলির সাথে দক্ষ প্রোগ্রামিং" বা "প্রোগ্রামিং কথোপকথন" উভয়ই ধারাবাহিকের মধ্যে প্রথম একটি।
alfC

1
@becko বাস্তবিক সেখানে দেখুন Alex এর বিন্দু থেকে প্রতি নির্দেশ নীচে একটি উত্তর stackoverflow.com/a/23329089/225186
alfC

উত্তর:


71

সংকলকটি জানতে পারবে না আপনি পয়েন্টার তুলনা বা গভীর (অভ্যন্তরীণ) তুলনা চেয়েছিলেন কিনা।

এটি কেবল এটি বাস্তবায়ন না করা এবং প্রোগ্রামারকে সেগুলি নিজেই করতে দেওয়া নিরাপদ। তারপরে তারা তাদের পছন্দ মতো সমস্ত অনুমান করতে পারে।


292
এই সমস্যাটি কোনও অনুলিপি তৈরি করতে বাধা দেয় না, যেখানে এটি বেশ ক্ষতিকারক।
MSalters

78
অনুলিপি কনস্ট্রাকটর (এবং operator=) সাধারণত তুলনা অপারেটরদের হিসাবে একই প্রেক্ষাপটে কাজ - যে, একটি প্রত্যাশা যে আপনার সঞ্চালন পরে a = b, a == bসত্য। operator==সংকলকটি এটির মতো একই সামগ্রিক মান শব্দার্থক ব্যবহার করে একটি ডিফল্ট সরবরাহ করা স্পষ্টতই বোধগম্য হয় operator=। আমি সন্দেহ করি যে এখানে পেরেেসবাল আসলেই সঠিক operator=(এবং অনুলিপি কর্টর) একমাত্র সি সামঞ্জস্যের জন্য সরবরাহ করা হয়েছে এবং তারা পরিস্থিতি আরও খারাপ করতে চায় না।
পাভেল মিনায়েভ

46
-1। অবশ্যই আপনি একটি গভীর তুলনা চান, প্রোগ্রামার যদি একটি পয়েন্টার তুলনা করতে চায়, তবে সে লিখত (& f1 == & f2)
ভিক্টর সেহর

62
ভিক্টর, আমি আপনাকে আপনার প্রতিক্রিয়াটি পুনরায় চিন্তা করার পরামর্শ দিচ্ছি। ক্লাস ফুতে যদি একটি বার * থাকে, তবে সংকলক কীভাবে জানতে পারবে যে ফু :: অপারেটর == বার * এর ঠিকানা, বা বারের বিষয়বস্তু তুলনা করতে চায় কিনা?
ইঙ্গ্রামটি

46
@ মার্ক: এটিতে যদি কোনও পয়েন্টার থাকে তবে পয়েন্টার মানের সাথে তুলনা করা যুক্তিসঙ্গত - যদি এতে কোনও মান থাকে তবে মানগুলির তুলনা করা যুক্তিসঙ্গত। ব্যতিক্রমী পরিস্থিতিতে প্রোগ্রামার ওভাররাইড করতে পারে। এটি ঠিক যেমন ভাষাটি ইনট এবং পয়েন্টার-টু-ইনটগুলির মধ্যে তুলনা প্রয়োগ করে।
ইমন নের্বোন

317

আর্গুমেন্ট যে সংকলক যদি একটি ডিফল্ট অনুলিপি নির্মাণকারীর সরবরাহ করতে পারে তবে এটি একটি অনুরূপ ডিফল্ট সরবরাহ করতে সক্ষম হওয়া উচিত operator==()নির্দিষ্ট পরিমাণে বোধ তৈরি করে। আমি মনে করি যে এই অপারেটরের জন্য একটি সংকলক উত্পাদিত ডিফল্ট সরবরাহ না করার সিদ্ধান্তের কারণটি স্ট্রস্ট্রুপ "সি ++ এর ডিজাইন এবং বিবর্তন" -এ ডিফল্ট অনুলিপি নির্মাণকারীর সম্পর্কে যা বলেছিল তা দ্বারা অনুমান করা যায় (ধারা 11.4.1 - অনুলিপি নিয়ন্ত্রণ) :

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

সুতরাং "কেন সি ++ এর ডিফল্ট থাকে না operator==()?" এর পরিবর্তে, প্রশ্নটি হওয়া উচিত ছিল "কেন সি ++ এর একটি ডিফল্ট অ্যাসাইনমেন্ট এবং অনুলিপি নির্মাতা আছে?", উত্তরটি সেই আইটেমগুলিতে অনিচ্ছাকৃতভাবে সিটির সাথে সামনের সামঞ্জস্যের জন্য স্ট্রোস্ট্রুপের অন্তর্ভুক্ত ছিল with (সম্ভবত সি ++ এর বেশিরভাগ ওয়ার্টের কারণ, তবে সম্ভবত সি ++ এর জনপ্রিয়তার প্রাথমিক কারণ)।

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


29
ভাল উত্তর. আমি কেবল উল্লেখ করতে চাই যে সি ++ 11 এ, এসাইনমেন্ট অপারেটর এবং অনুলিপি কনস্ট্রাক্টরকে ব্যক্তিগত করার পরিবর্তে আপনি তাদের পুরোপুরি এভাবে মুছে ফেলতে পারেন: Foo(const Foo&) = delete; // no copy constructorএবংFoo& Foo=(const Foo&) = delete; // no assignment operator
করাদোক

9
"তবে, সি ++ এর ডিফল্ট অ্যাসাইনমেন্ট এবং সি থেকে নির্মাতাদের অনির্দিষ্টভাবে উত্তরাধিকার সূত্রে প্রাপ্ত হয়েছে" এটি আপনাকে বোঝাতে পারে না যে আপনাকে কেন এইভাবে সমস্ত সি ++ প্রকার তৈরি করতে হবে। তাদের কেবল এটিকে সাদামাটা পুরানো পিওডিগুলিতে সীমাবদ্ধ করা উচিত ছিল, কেবলমাত্র প্রকারের মধ্যে যা ইতিমধ্যে সিতে রয়েছে, আর নেই no
থেইসেন্ট

3
আমি অবশ্যই বুঝতে পারি যে সি ++ কেন এই আচরণগুলি উত্তরাধিকার সূত্রে পেয়েছে struct, তবে আমি চাই যে এটি classআলাদাভাবে (এবং বুদ্ধিমানভাবে) আচরণ করবে । প্রক্রিয়াটিতে এটি ডিফল্ট অ্যাক্সেসের মধ্যে structএবং classপাশে আরও অর্থবহ পার্থক্য দিত ।
জেমসডলিন

@ জেমসডলিন যদি আপনি কোনও নিয়ম চান, তবে ডেটর ঘোষিত হলে অন্তর্নিহিত ঘোষণা এবং সিটারের সংজ্ঞা এবং অ্যাসাইনমেন্টটি অক্ষম করে রাখলে এটি সার্থক হবে।
Deduplicator

1
আমি এখনও প্রোগ্রামারকে স্পষ্টরূপে একটি তৈরির জন্য সংকলকটি অর্ডার দেওয়ার কোনও ক্ষতি দেখতে পাই না operator==। এই মুহুর্তে এটি কিছু বয়লার-প্লেট কোডের জন্য কেবল সিনট্যাক্স চিনির। আপনি যদি ভয় পান যে এইভাবে প্রোগ্রামার শ্রেণিবদ্ধ ক্ষেত্রগুলির মধ্যে কিছু পয়েন্টারকে উপেক্ষা করতে পারে তবে আপনি একটি শর্ত যোগ করতে পারেন যে এটি কেবলমাত্র আদিম ধরণের এবং অবজেক্টগুলিতে কাজ করতে পারে যেগুলি নিজেরাই সমতা অপারেটর রয়েছে। যদিও এটিকে পুরোপুরি অস্বীকার করার কোনও কারণ নেই।
NO_NAME

93

এমনকি সি ++ ২০ তেও, সংকলকটি এখনও operator==আপনার জন্য স্পষ্টভাবে জেনারেট করে না

struct foo
{
    std::string str;
    int n;
};

assert(foo{"Anton", 1} == foo{"Anton", 1}); // ill-formed

তবে আপনি C ++ 20 সাল থেকে স্পষ্টভাবে ডিফল্ট করার ক্ষমতা অর্জন করবেন :==

struct foo
{
    std::string str;
    int n;

    // either member form
    bool operator==(foo const&) const = default;
    // ... or friend form
    friend bool operator==(foo const&, foo const&) = default;
};

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

assert(foo{"Anton", 1} == foo{"Anton", 1}); // ok!
assert(foo{"Anton", 1} != foo{"Anton", 2}); // ok!

এই নির্দিষ্ট বৈশিষ্ট্য (খেলাপি operator==মধ্যে প্রতিসাম্য ==এবং !=) থেকে আসে এক প্রস্তাব যে যে বৃহত্তর ভাষা বৈশিষ্ট্য অংশ ছিল operator<=>


আপনি কি জানেন যে এই সম্পর্কে আরও সাম্প্রতিক আপডেট আছে কিনা? এটি কি সি ++ 17 এ উপলব্ধ হতে চলেছে?
dcmm88

3
@ dcmm88 দুর্ভাগ্যক্রমে এটি সি ++ 17 এ উপলব্ধ হবে না। আমি উত্তর আপডেট করেছি।
আন্তন সাভিন

2
একটি পরিবর্তিত প্রস্তাব যা একই জিনিসকে (সংক্ষিপ্ত ফর্ম ব্যতীত) অনুমতি দেয় এটি সি ++ ২০ তে হবে যদিও :)
রকেট 1111

সুতরাং মূলত আপনাকে নির্দিষ্ট করতে হবে = default, যেটি ডিফল্টরূপে তৈরি হয়নি, তাই না? এটি আমার কাছে অক্সিমরনের মতো শোনাচ্ছে ("স্পষ্টতই ডিফল্ট")।
আর্টিন

@ আর্টিন এটি বোঝায় যে ভাষায় নতুন বৈশিষ্ট্য যুক্ত করার ফলে বিদ্যমান বাস্তবায়নটি ভাঙ্গা উচিত নয়। নতুন লাইব্রেরির মান যুক্ত করা বা নতুন জিনিস সংকলক করতে পারে one নতুন সদস্য ফাংশনগুলি যুক্ত করা যেখানে তাদের অস্তিত্ব ছিল না সেখানে সম্পূর্ণ ভিন্ন গল্প। আপনার প্রকল্পকে ভুল থেকে সুরক্ষিত করার জন্য আরও অনেক প্রচেষ্টা প্রয়োজন। সুস্পষ্ট এবং অন্তর্নিহিত ডিফল্টের মধ্যে স্যুইচ করতে আমি ব্যক্তিগতভাবে সংকলক পতাকাটি পছন্দ করব। আপনি পুরানো সি ++ স্ট্যান্ডার্ড থেকে প্রকল্পটি তৈরি করেন, সংকলক পতাকা দ্বারা সুস্পষ্ট ডিফল্ট ব্যবহার করুন। আপনি ইতিমধ্যে সংকলক আপডেট করেছেন যাতে আপনার এটি সঠিকভাবে কনফিগার করা উচিত। নতুন প্রকল্পগুলির জন্য এটি অন্তর্ভুক্ত করুন make
ম্যাকিয়েজ জাউউকি

44

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

যথাযথ স্মার্ট পয়েন্টার ব্যবহার করার সময় (যেমন: স্ট্যান্ড :: শেয়ারড_পিটার) ডিফল্ট অনুলিপি নির্মাণকারী সাধারণত ভাল থাকে এবং হাইপোথিটিকাল ডিফল্ট তুলনা অপারেটরের সুস্পষ্ট বাস্তবায়নও ঠিক হবে।


39

এর জবাব দেওয়া হল যে সি ++ করেনি == কারণ সি করেনি, এবং এখানে কেন সি প্রথমে ডিফল্ট = তবে কোনও == সরবরাহ করে না। সি এটি সহজ রাখতে চেয়েছিল: সি প্রয়োগ করা = মেমকপি দ্বারা; তবে, == প্যাডিংয়ের কারণে মেমক্যাম্প দ্বারা প্রয়োগ করা যায় না। প্যাডিং শুরু না হওয়ার কারণে, মেমক্যাম্প বলছে যে তারা একই হলেও তারা আলাদা। খালি শ্রেণীর জন্য একই সমস্যা বিদ্যমান: মেমক্যাম্প বলছে যে তারা আলাদা কারণ খালি শ্রেণীর আকার শূন্য নয়। এটা যে বাস্তবায়নে == আরো কিছু কোড সি = বাস্তবায়ন চেয়ে জটিল উপরে থেকে দেখা যায় উদাহরণস্বরূপ এই সংক্রান্ত। আমি ভুল হলে আপনার সংশোধন প্রশংসা করা হয়।


6
সি ++ এর জন্য মেমকি ব্যবহার করে না operator=- এটি কেবল পিওড প্রকারের জন্যই কাজ করবে, তবে সি ++ operator=নন পিওডি ধরণের ক্ষেত্রেও একটি ডিফল্ট সরবরাহ করে।
ফ্লেক্সো

2
হ্যাঁ, সি ++ প্রয়োগ হয়েছে = আরও পরিশীলিত পদ্ধতিতে। দেখে মনে হচ্ছে এটি কেবল কার্যকর হয়েছে = একটি সাধারণ মেমকপি সহ।
রিও উইং

এই উত্তরের বিষয়বস্তু মাইকেল এর সাথে একত্রিত করা উচিত। তার প্রশ্নটি সংশোধন করে তারপর এটি উত্তর দেয়।
Sgene9

27

এই ভিডিওতে এসটিএলের স্রষ্টা অ্যালেক্স স্টেপানভ প্রায় 13:00 টায় এই প্রশ্নের খুব সম্বোধন করেছেন। সংক্ষেপে বলতে গেলে, সি ++ এর বিবর্তন দেখে তিনি যুক্তি দেখান যে:

  • এটি দুর্ভাগ্যজনক যে == এবং! = সুস্পষ্টভাবে ঘোষণা করা হয়নি (এবং বর্জন তার সাথে সম্মত)। একটি সঠিক ভাষায় আপনার জন্য সেই জিনিসগুলি প্রস্তুত থাকতে হবে (তিনি আরও পরামর্শ দিয়েছিলেন যে আপনি একটি সংজ্ঞা দিতে সক্ষম হবেন না ! = যা শব্দার্থকে ভেঙে দেয় == )
  • কারণ এই ক্ষেত্রে এর শিকড় আছে হয় সি ওপেন সোর্স লাইসেন্সে কোনো (সি ++ বহু সমস্যা হিসাবে) নিয়োগ অপারেটর পরোক্ষভাবে সঙ্গে সংজ্ঞায়িত করা হয় বিট নিয়োগ অল্পে কিন্তু যে কাজ হবে না == । আরও একটি বিশদ বিবরণ বার্জন স্ট্রস্ট্রপ থেকে এই নিবন্ধে পাওয়া যাবে ।
  • ফলোআপ প্রশ্নে কেন তখন সদস্যের তুলনায় কোনও সদস্য ব্যবহার করা হয়নি কারণ তিনি একটি আশ্চর্যজনক কথা বলেছেন : সি এক ধরনের স্বজাতীয় ভাষা ছিল এবং রিচির জন্য এই জিনিসগুলি প্রয়োগকারী লোক তাকে বলেছিল যে এটি কার্যকর করা তার পক্ষে কঠিন বলে মনে হয়েছে!

তারপরে তিনি বলেছেন যে (দূরবর্তী) ভবিষ্যতে == এবং ! = সুস্পষ্টভাবে উত্পন্ন হবে।


2
দেখে মনে হচ্ছে এই দূরবর্তী ভবিষ্যতটি 2017 বা 18 বা 19 হতে চলেছে না, ভাল আপনি আমার
প্রবাহকে ধরেন

18

সি ++ 20 সহজেই একটি ডিফল্ট তুলনা অপারেটর বাস্তবায়নের একটি উপায় সরবরাহ করে।

Cppreferences.com থেকে উদাহরণ :

class Point {
    int x;
    int y;
public:
    auto operator<=>(const Point&) const = default;
    // ... non-comparison functions ...
};

// compiler implicitly declares operator== and all four relational operators work
Point pt1, pt2;
if (pt1 == pt2) { /*...*/ } // ok, calls implicit Point::operator==
std::set<Point> s; // ok
s.insert(pt1); // ok
if (pt1 <= pt2) { /*...*/ } // ok, makes only a single call to Point::operator<=>

4
আমি বিস্মিত যে তারা ব্যবহৃত Pointএকটি জন্য একটি উদাহরণ হিসাবে ক্রম অপারেশন যেহেতু অর্ডার করার কোন যুক্তিসঙ্গত ডিফল্ট উপায়ে সঙ্গে দুই পয়েন্ট xএবং yস্থানাঙ্ক ...
নল

4
@ পাইপ আপনি যদি উপাদানগুলি কোন ক্রমে যত্নশীল না হন তবে ডিফল্ট অপারেটরটি ব্যবহার করা অর্থপূর্ণ। উদাহরণস্বরূপ, আপনি std::setনিশ্চিত করতে ব্যবহার করতে পারেন যে সমস্ত পয়েন্ট অনন্য, এবং কেবলমাত্র std::setব্যবহার করে operator<
vll

রিটার্ন টাইপ সম্পর্কে auto: জন্য এই ক্ষেত্রে আমরা সবসময় অনুমান করতে পারেন এটা হবে std::strong_orderingথেকে #include <compare>?
কেভিনার্পে

1
@ কেভিনার্পে রিটার্নের ধরণটি std::common_comparison_category_tএই শ্রেণীর জন্য ডিফল্ট ক্রম ( std::strong_ordering) হয়ে যায় ।
vll

15

ডিফল্ট সংজ্ঞায়িত করা সম্ভব নয় ==, তবে আপনি নিজেরাই ডিফল্টটি সংজ্ঞায়িত করতে পারেন যার !=মাধ্যমে ==সাধারণত নিজেকে সংজ্ঞায়িত করা উচিত। এর জন্য আপনার নিম্নলিখিত বিষয়গুলি করা উচিত:

#include <utility>
using namespace std::rel_ops;
...

class FooClass
{
public:
  bool operator== (const FooClass& other) const {
  // ...
  }
};

বিশদ জানতে আপনি http://www.cplusplus.com/references/std/utility/rel_ops/ দেখতে পারেন ।

আপনি যদি সংজ্ঞায়িত করেন তবে ব্যবহারের সময় operator< <=,>,> = এর জন্য অপারেটরগুলি এটি থেকে হ্রাস করা যেতে পারে std::rel_ops

তবে আপনি যখন ব্যবহার করবেন তখন আপনার সতর্কতা অবলম্বন করা উচিত std::rel_opsকারণ তুলনা অপারেটরগুলি যে ধরণের জন্য আপনি প্রত্যাশিত নন তার জন্য ছাড় দেওয়া যেতে পারে।

বেসিকটি থেকে সম্পর্কিত অপারেটরকে ছাড়ের আরও পছন্দের উপায় হ'ল :: অপারেটরগুলি ব্যবহার করা ।

বুস্টে ব্যবহৃত পদ্ধতিরটি আরও ভাল কারণ এটি আপনার কেবলমাত্র শ্রেণীর জন্য অপারেটরের ব্যবহার সংজ্ঞায়িত করে, সমস্ত শ্রেণীর জন্য নয় for

আপনি "+" "থেকে" + "" - "" থেকে = "ইত্যাদি তৈরি করতে পারেন ... (সম্পূর্ণ তালিকা এখানে দেখুন )


অপারেটর !=লেখার পরে আমি ডিফল্ট পেলাম না ==। অথবা আমি করেছি তবে তাতে constনেসের অভাব ছিল । এটি আমার নিজেরও লিখতে হয়েছিল এবং সব ঠিক আছে।
জন

প্রয়োজনীয় ফলাফল অর্জন করতে আপনি কনস্ট-নেসের সাথে খেলতে পারেন। কোড ব্যতীত এটিতে কী ভুল তা বলা মুশকিল।
সার্জটেক

2
rel_opsসি ++ ২০ তে একটি কারণ হ্রাস করা হয়েছিল: কারণ এটি কাজ করে না , কমপক্ষে সর্বত্র নয় এবং অবশ্যই ধারাবাহিকভাবে নয়। sort_decreasing()সংকলন পাওয়ার কোনও নির্ভরযোগ্য উপায় নেই । অন্যদিকে, বুস্ট.অ্যাপ্রেটাররা সর্বদা কাজ করে এবং কাজ করে।
ব্যারি

10

সি ++ 0x এর ডিফল্ট ফাংশনগুলির জন্য একটি প্রস্তাব ছিল, সুতরাং আপনি বলতে পারেন যে default operator==; আমরা শিখেছি যে এটি এই বিষয়গুলি সুস্পষ্ট করতে সহায়তা করে।


3
আমি ভেবেছিলাম যে কেবলমাত্র "বিশেষ সদস্য ফাংশন" (ডিফল্ট কনস্ট্রাক্টর, কপি কনস্ট্রাক্টর, এসাইনমেন্ট অপারেটর এবং ডেস্ট্রাক্টর) স্পষ্টতই খেলাপি হতে পারে। তারা কি এটি অন্য কিছু অপারেটরের কাছে প্রসারিত করেছে?
মাইকেল বার বার

4
মুভ কনস্ট্রাক্টরকেও খেলাপি করা যায়, তবে আমি মনে করি না এটি প্রযোজ্য operator==। যা দুঃখের বিষয়।
পাভেল মিনায়েভ

5

ধারণাগতভাবে সমতার সংজ্ঞা দেওয়া সহজ নয়। এমনকি পিওডির ডেটাগুলির জন্য, কেউ যুক্তি দিতে পারে যে ক্ষেত্রগুলি সমান হলেও এটি পৃথক বস্তু (পৃথক ঠিকানায়) এটি সমান নয়। এটি আসলে অপারেটরের ব্যবহারের উপর নির্ভর করে। দুর্ভাগ্যক্রমে আপনার সংকলক মানসিক নয় এবং এটি অনুমান করতে পারে না।

এগুলি ছাড়া পায়ে নিজেকে গুলি করার জন্য ডিফল্ট ফাংশনগুলি দুর্দান্ত উপায়। আপনার বর্ণিত ডিফল্টগুলি পিওডি স্ট্রাক্টের সাথে সামঞ্জস্য রাখতে মূলত রয়েছে। যদিও তারা বিকাশকারীদের সম্পর্কে ভুলে যাওয়া বা ডিফল্ট বাস্তবায়নের শব্দার্থবিজ্ঞানের তুলনায় পর্যাপ্ত পরিমাণে ধ্বংসযজ্ঞ সৃষ্টি করে।


10
পিওডি স্ট্রাক্টগুলির জন্য কোনও অস্পষ্টতা নেই - তাদের অন্য কোনও পিওডি টাইপের মতো ঠিক একই আচরণ করা উচিত, যা মান সমতা (বরং তারপরে সাম্যতার উল্লেখ)। এক intঅপরের থেকে কপি ctor মাধ্যমে তৈরি এক যা থেকে এটা তৈরি করা হয়েছে সমান; structদুটি intক্ষেত্রের একটির জন্য একমাত্র যৌক্তিক কাজ হ'ল সঠিকভাবে কাজ করা।
পাভেল মিনায়েভ

1
@ এমজিউকা: আমি সর্বজনীন সমতা সম্পর্কের জন্য যথেষ্ট কার্যকারিতা দেখতে পাচ্ছি যা কোনও শব্দ বা অভিধানের অনুরূপ সংগ্রহের মূল হিসাবে ব্যবহার করার মানকে বিবেচনা করে এমন কোনও ধরণের অনুমতি দেয়। এই ধরনের সংগ্রহগুলি কোনও গ্যারান্টিযুক্ত-রিফ্লেক্সিভ সমতুল্য সম্পর্ক ছাড়া কার্যকরভাবে আচরণ করতে পারে না। আইএমএইচও, সর্বোত্তম সমাধানটি হ'ল একটি নতুন অপারেটর সংজ্ঞায়িত করা যা সমস্ত অন্তর্নির্মিত প্রকারগুলি সংবেদনশীলভাবে প্রয়োগ করতে পারে এবং কিছু নতুন পয়েন্টার প্রকারের সংজ্ঞা দেয় যা বিদ্যমানগুলির মতো ছিল কিছু বাদে সমতাটিকে রেফারেন্স ইক্যুয়ালিটি হিসাবে চিহ্নিত করবে অন্যরা লক্ষ্যগুলির সাথে সামঞ্জস্য রাখবে সমতা অপারেটর
সুপারক্যাট

1
@ সুপের্যাট উপমা অনুসারে, আপনি +অপারেটরের পক্ষে প্রায় একই যুক্তি তৈরি করতে পারেন যে এটি ভাসমানদের জন্য অসহযোগী; এটি (x + y) + z! = x + (y + z), এফপি রাউন্ডিংয়ের যে কারণে ঘটে। (যুক্তিযুক্তভাবে, ==এটি সাধারণ সংখ্যাসূচক মানের জন্য সত্য হওয়ার চেয়ে এটি আরও খারাপ সমস্যা )) আপনি একটি নতুন সংযোজন অপারেটর যুক্ত করার পরামর্শ দিতে পারেন যা সমস্ত সংখ্যার জন্য (এমনকি কোনও int) কাজ করে এবং এটি প্রায় একই রকম +তবে এটি সহযোগী ( একরকম)। তবে আপনি সেই ভাষায় সত্যই সাহায্য না করেই ভাষায় ফুলে ও বিভ্রান্তি যুক্ত করবেন।
এমজিচা

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

1
... আজকের তুলনায়) এবং এইভাবে তারা যে অসম্ভবটি করে না তা অবাক হওয়ার মতো বিষয় নয়। তবে কোনও সমতা সম্পর্ক বাস্তবায়নে কোনও মৌলিক বাধা নেই যা অনুলিপি করা যায় এমন কোনও মানের ক্ষেত্রে সর্বজনীনভাবে প্রযোজ্য।
সুপারক্যাট

1

এর কি কোনও ভাল কারণ আছে? সদস্য দ্বারা সদস্যের তুলনা করা কেন সমস্যা হবে?

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

এই উদাহরণটি বিবেচনা করুন, যেখানে verboseDescriptionসম্ভাব্য আবহাওয়া বিবরণের তুলনামূলকভাবে ছোট সেট থেকে একটি দীর্ঘ স্ট্রিং নির্বাচন করা হয়েছে।

class LocalWeatherRecord {
    std::string verboseDescription;
    std::tm date;
    bool operator==(const LocalWeatherRecord& other){
        return date==other.date
            && verboseDescription==other.verboseDescription;
    // The above makes a lot more sense than
     // return verboseDescription==other.verboseDescription
     //     && date==other.date;
    // because some verboseDescriptions are liable to be same/similar
    }
}

(অবশ্যই সংকলকটি তুলনার ক্রমটি উপেক্ষা করার অধিকারী হবে যদি এটি স্বীকৃতি দেয় যে তাদের কোনও পার্শ্ব-প্রতিক্রিয়া নেই তবে সম্ভবত সম্ভবত এটি উত্স কোড থেকে এটির ক্যু গ্রহণ করবে যেখানে এটির নিজস্ব কোনও ভাল তথ্য নেই))


আপনি যদি কোনও পারফরম্যান্সের সমস্যা খুঁজে পান তবে কেউ আপনাকে একটি অনুকূলকরণ-নির্ধারিত তুলনা লিখতে বাধা দেয় না। আমার অভিজ্ঞতার ক্ষেত্রে যদিও এটি একটি সংখ্যালঘু সংখ্যালঘু হবে।
পিটার - মনিকা পুনরায়

1

ঠিক যতক্ষণ সময় চলে যায় ততই এই প্রশ্নের উত্তরগুলি সম্পূর্ণ থেকে যায়: সি ++ 20 সাল থেকে এটি স্বয়ংক্রিয়ভাবে আদেশ দ্বারা উত্পন্ন হতে পারে auto operator<=>(const foo&) const = default;

এটি সমস্ত অপারেটর তৈরি করবে: ==,! =, <, <=,>, এবং> =, বিশদের জন্য https://en.cppreferences.com/w/cpp/language/default_comparisons দেখুন।

অপারেটরের চেহারার কারণে <=>এটিকে স্পেসশিপ অপারেটর বলা হয়। এছাড়াও দেখুন কেন আমাদের সি ++ এ স্পেসশিপ <=> অপারেটরের প্রয়োজন?

সম্পাদনা: এছাড়াও সি ++ 11 এ এর ​​জন্য একটি সুন্দর ঝরঝরে বিকল্প পাওয়া যায় যার সাথে একটি সম্পূর্ণ কোড উদাহরণের জন্য https://en.cppreferences.com/w/cpp/utility/tuple/tiestd::tie দেখুন । আকর্ষণীয় অংশটি, যা দিয়ে কাজ করা হয়েছে তা হ'ল:bool operator<(…)==

#include <tuple>

struct S {
………
bool operator==(const S& rhs) const
    {
        // compares n to rhs.n,
        // then s to rhs.s,
        // then d to rhs.d
        return std::tie(n, s, d) == std::tie(rhs.n, rhs.s, rhs.d);
    }
};

std::tie সমস্ত তুলনা অপারেটরদের সাথে কাজ করে এবং সংকলক দ্বারা সম্পূর্ণ অপ্টিমাইজড।


-1

আমি সম্মত, পিওড টাইপ ক্লাসের জন্য তখন সংকলকটি এটি আপনার জন্য করতে পারে। তবে আপনি যেটি সহজ সংকলক হিসাবে বিবেচনা করতে পারেন তা ভুল হয়ে যেতে পারে। সুতরাং প্রোগ্রামারটিকে এটি করা ভাল।

আমার একবার একটি পিওডি কেস হয়েছিল যেখানে দুটি ক্ষেত্র অনন্য ছিল - তাই তুলনা কখনই সত্য বলে বিবেচিত হবে না। যাইহোক আমার তুলনা কেবল পিলোডের সাথে তুলনা করার প্রয়োজন ছিল - এমন কিছু যা সংকলকটি কখনই বুঝতে পারে না বা এটি নিজেই বের করতে পারে।

পাশাপাশি - তারা কি লিখতে বেশি সময় নেয় না ?!

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