স্বচ্ছ তুলনামূলক কি?


106

সি ++ ১৪-এ, এসোসিয়েটিভ পাত্রে সি ++ 11 থেকে পরিবর্তন হয়েছে বলে মনে হয় - [এসোসিয়েটিভ.আরকিমিটস / 13 বলেছেন:

সদস্য ফাংশন টেমপ্লেট find, count, lower_bound, upper_bound, এবং equal_rangeজমিদার রেজোলিউশনের যদি না টাইপ অংশগ্রহণের করবে না Compare::is_transparentবিদ্যমান।

তুলনামূলক "স্বচ্ছ" করার উদ্দেশ্য কী?

সি ++ 14 এছাড়াও লাইব্রেরির টেম্পলেট সরবরাহ করে:

template <class T = void> struct less {
    constexpr bool operator()(const T& x, const T& y) const;
    typedef T first_argument_type;
    typedef T second_argument_type;
    typedef bool result_type;
};

template <> struct less<void> {
    template <class T, class U> auto operator()(T&& t, U&& u) const
    -> decltype(std::forward<T>(t) < std::forward<U>(u));
    typedef *unspecified* is_transparent;
};

সুতরাং উদাহরণস্বরূপ, একটি স্বচ্ছ তুলনা std::set<T, std::less<T>>করতে হবে না , কিন্তু একটি std::set<T, std::less<>> হবে

এটি কোন সমস্যাটি সমাধান করে এবং স্ট্যান্ডার্ড পাত্রে কীভাবে কাজ করে তা এই পরিবর্তন করে? উদাহরণস্বরূপ, এর টেমপ্লেট পরামিতি std::setএখনও Key, Compare = std::less<Key>, ..., তাই ডিফল্ট সেট তার হারান নেই find, countইত্যাদি সদস্যদের?


উদাহরণস্বরূপ, এই cppreferences বিবরণ দেখুন । এবং আমি এখন বোকা বোধ করছি, কারণ আমি "সদস্য ফাংশন টেম্পলেট " শব্দটি লক্ষ করছি ...
কেরেক এসবি

5
সম্ভবত সম্পর্কিত: stackoverflow.com/questions/18939882/...

সিপ্রেফারেন্সের en.cppreferences.com/w/cpp/utility/functional/less_void- এ ব্লব রয়েছে
কিবিবি

উত্তর:


60

এটি কোন সমস্যার সমাধান করে,

দেখুন Dietmar এর উত্তর এবং remyabel এর উত্তর

এবং এটি কীভাবে স্ট্যান্ডার্ড পাত্রে কাজ করে তা পরিবর্তন করে?

না, ডিফল্টরূপে নয়।

এর নতুন সদস্য ফাংশন টেম্পলেট ওভারলোডগুলি findআপনাকে কী টাইপটি ব্যবহার না করে পাত্রে কী এর সাথে তুলনীয় এমন একটি প্রকারের ব্যবহার করতে দেয়। যৌক্তিকতা এবং এই বৈশিষ্ট্যটি যুক্ত করার জন্য একটি বিশদ, সাবধানে লিখিত প্রস্তাবের জন্য জোয়াকান মো লেপেজ মুউজের N3465 দেখুন ।

ব্রিস্টল বৈঠকে এলডাব্লুজি সম্মতি জানায় যে বৈচিত্র্যপূর্ণ অনুসন্ধানের বৈশিষ্ট্যটি দরকারী এবং আকাঙ্ক্ষিত, তবে আমরা নিশ্চিত হতে পারি না যে জ্যাকউনের প্রস্তাবটি সব ক্ষেত্রেই নিরাপদ থাকবে। N3465 প্রস্তাব কিছু প্রোগ্রামের জন্য গুরুতর সমস্যা সৃষ্টি করতে পারে ( বিদ্যমান কোড বিভাগে প্রভাব দেখুন )। জোয়াকন বিভিন্ন ট্রেড-অফগুলির সাথে কিছু বিকল্প বাস্তবায়ন সহ একটি আপডেট করা খসড়া প্রস্তাব প্রস্তুত করেছিলেন, যা এলডাব্লুজিকে বিভিন্ন উপকারিতা বোঝার জন্য খুব দরকারী ছিল, তবে তারা সকলেই কিছু উপায়ে কিছুটা ভেঙে ফেলার ঝুঁকি নিয়েছিল যাতে বৈশিষ্ট্যটি যুক্ত করার পক্ষে কোনও sensক্যমত্য হয়নি। আমরা স্থির করেছি যে শর্তহীন বৈশিষ্ট্যটি যুক্ত করা নিরাপদ না হলেও এটি ডিফল্টরূপে অক্ষম থাকলে এবং কেবলমাত্র "অপ্ট ইন" করা নিরাপদ হবে।

N3657 প্রস্তাবের মূল পার্থক্যটি (যা N3465 এর উপর ভিত্তি করে আমার এবং এসটিএল দ্বারা শেষ মুহূর্তে সংশোধন করা হয়েছিল এবং জোয়াকুনের পরে অপ্রকাশিত খসড়া) is_transparentপ্রোটোকল হিসাবে প্রকারটি যুক্ত করা হয়েছিল যা নতুন কার্যকারিতাটি বেছে নিতে ব্যবহার করতে পারে।

আপনি যদি "স্বচ্ছ ফান্টেক্টর" ব্যবহার করেন না (যেমন একটি is_transparentপ্রকার সংজ্ঞায়িত করে ) তবে পাত্রে তারা সর্বদা যেমন করে তেমন আচরণ করে এবং এটি এখনও ডিফল্ট।

যদি আপনি ব্যবহার করতে চান std::less<>(যা সি ++ 14 এর জন্য নতুন) বা অন্য কোনও "স্বচ্ছ ফান্টেক্টর" টাইপ করুন তবে আপনি নতুন কার্যকারিতা পাবেন।

std::less<>ওরফে টেমপ্লেটগুলির সাহায্যে ব্যবহার করা সহজ:

template<typename T, typename Cmp = std::less<>, typename Alloc = std::allocator<T>>
  using set = std::set<T, Cmp, Alloc>;

নামটি is_transparentএসটিএল এর N3421 থেকে এসেছে যা "হীরা অপারেটর" কে সি ++ 14 এ যুক্ত করেছে। একটি "স্বচ্ছ ফান্টেক্টর" হ'ল যা কোনও আর্গুমেন্টের ধরণগুলি গ্রহণ করে (যা একই রকম হতে হবে না) এবং সেই যুক্তিগুলি কেবল অন্য অপারেটরে প্রেরণ করে। এই জাতীয় ফান্টরটি is_transparentহ'ল সংঘবদ্ধ পাত্রে ভিন্নজাতীয় অনুসন্ধানের জন্য যা চান, তাই হ'ল তাই এই টাইপটি সমস্ত হীরা অপারেটরগুলিতে যুক্ত করা হয়েছিল এবং নতুন ফাংশনটিটিটি এসোসিয়েটিভ পাত্রে সক্ষম করা উচিত তা নির্দেশ করার জন্য ট্যাগ টাইপ হিসাবে ব্যবহৃত হয়েছিল। প্রযুক্তিগতভাবে, ধারকগুলিকে "স্বচ্ছ ফান্টর" লাগবে না, কেবলমাত্র এটি একে ভিন্নধর্মী প্রকারের সাহায্যে কল করতে সমর্থন করে (যেমন https://stackoverflow.com/a/18940595/981959-তেpointer_comp টাইপটি এসটিএল এর সংজ্ঞা অনুসারে স্বচ্ছ নয়,pointer_comp::is_transparentএটি সমস্যার সমাধান করতে ব্যবহার করার অনুমতি দেয়)। আপনি যদি কেবলমাত্র std::set<T, C>কীগুলির সাথে কী অনুসন্ধান করেন Tবা intতারপরে Cকেবলমাত্র ধরণের যুক্তি Tএবং int(উভয় ক্রমে) কল করার প্রয়োজন হয় তবে এটি সত্যিকারের স্বচ্ছ হওয়ার দরকার নেই। আমরা সেই নামটি আংশিকভাবে ব্যবহার করেছি কারণ আমরা আরও ভাল নামটি নিয়ে আসতে পারিনি (আমি পছন্দ করতাম is_polymorphicকারণ এই জাতীয় ফ্যান্ট্যাক্টরা স্ট্যাটিক পলিমারফিজম ব্যবহার করে তবে ইতিমধ্যে একটি std::is_polymorphicধরণের বৈশিষ্ট্য রয়েছে যা গতিশীল পলিমারফিজমকে বোঝায়)।


3
আরে, আপনি কি সেই ব্যক্তি ছিলেন যার সাথে এসটিএল বলেছিল, "আপনি অবশ্যই আপনার মাথার মধ্যে টেম্পলেট যুক্তি ছাড়িয়ে নিতে পারেন" টক উল স্টারের সাথে যুক্ত?
কেরেক এসবি 21

10
না, আমি সেখানে ছিলাম না, তবে এমন লোকেরা আছে যাদের মাথায় অনেক বেশি মেনে চলার সংকলক রয়েছে :)
জোনাথন ওয়েকেলি

আমি অনুমান করি যে "হীরা অপারেটর" <>লিঙ্কযুক্ত প্রস্তাবকে বোঝায় , কিন্তু সেই প্রস্তাবটি প্রবর্তন করেনি <>- এটি একটি খালি টেম্পলেট প্যারামিটার তালিকার বিদ্যমান বাক্য গঠন রয়েছে। "ডায়মন্ড অপারেটর ফান্টেক্টর" কিছুটা বিভ্রান্ত হবে।
কিওয়ার্টি

33

সি ++ 11 সেখানে সদস্য টেমপ্লেট নয় find(), lower_bound()ইত্যাদি অর্থাৎ কিছুই এই পরিবর্তনের ফলে হারিয়ে গেছে। এসোসিয়েটিভ পাত্রে বিজাতীয় কীগুলি ব্যবহার করার অনুমতি দেওয়ার জন্য সদস্য টেম্পলেটগুলি n3657 দিয়ে প্রবর্তিত হয়েছিল। ভাল ও খারাপ যে উদাহরণটি ব্যতীত এটি কার্যকর সেখানে আমি কোনও দৃ concrete় উদাহরণ দেখছি না!

is_transparentব্যবহারের অবাঞ্ছিত ধর্মান্তর এড়াতে উদ্দেশ্যে। যদি সদস্য টেমপ্লেটগুলি নিয়ন্ত্রণহীন থাকে তবে বিদ্যমান কোডগুলি সরাসরি অবজেক্টগুলির মধ্যে দিয়ে যেতে পারে যা সদস্য টেমপ্লেটগুলি ছাড়া রূপান্তরিত হত। উদাহরণস্বরূপ n3657 থেকে std::set<std::string>স্ট্রিং আক্ষরিক ব্যবহার করে কোনও অবজেক্টের অবস্থান চিহ্নিত করা হচ্ছে : C ++ 11 সংজ্ঞার std::stringসাথে সংশ্লিষ্ট সদস্য ফাংশনটিতে স্ট্রিং ল্যাটারালগুলি পাস করার সময় একটি অবজেক্ট তৈরি করা হয়। পরিবর্তনের সাথে সাথে সরাসরি স্ট্রিং আক্ষরিক ব্যবহার সম্ভব। অন্তর্নিহিত তুলনা ফাংশন অবজেক্টটি যদি একচেটিয়াভাবে প্রয়োগ করা হয় তবে std::stringএটি খারাপ কারণ এখন std::stringপ্রতিটি তুলনার জন্য একটি তৈরি করা হবে। অন্যদিকে, অন্তর্নিহিত তুলনা ফাংশন অবজেক্টটি যদি একটি নিতে পারেstd::string এবং একটি স্ট্রিং আক্ষরিক, এটি একটি অস্থায়ী অবজেক্টের নির্মাণ এড়াতে পারে।

is_transparentতুলনা ফাংশন অবজেক্টে নেস্টেড টাইপটি প্রলুব্ধ সদস্য ফাংশনটি ব্যবহার করা উচিত কিনা তা নির্দিষ্ট করার একটি উপায় সরবরাহ করে: তুলনা ফাংশন অবজেক্ট যদি ভিন্ন ভিন্ন যুক্তিগুলির সাথে মোকাবিলা করতে পারে তবে এটি এই ধরণের সংজ্ঞা দেয় যে এটি দক্ষতার সাথে বিভিন্ন যুক্তি মোকাবেলা করতে পারে। উদাহরণস্বরূপ, নতুন অপারেটর ফাংশন অবজেক্টগুলি কেবল প্রতিনিধিত্ব করে operator<()এবং স্বচ্ছ বলে দাবি করে। এটি অন্ততপক্ষে কাজ করে std::stringযার জন্য তাত্পর্য char const*হিসাবে অপারেটররা কম ওভারলোড হয়ে গেছে । যেহেতু এই ফাংশন অবজেক্টগুলিও নতুন, যদিও তারা ভুল কাজ করে (যেমন কোনও প্রকারের জন্য রূপান্তর প্রয়োজন) এটি কমপক্ষে পারফরম্যান্সের অবক্ষয়ের ফলে নিঃশব্দ পরিবর্তন হবে না।


ধন্যবাদ - অন্য প্রশ্নে আমার মন্তব্য দেখুন: আপনি কি স্বচ্ছ আচরণটি ডিফল্টরূপে পান?
কেরেক এসবি

8
@KerrekSB: স্বচ্ছ আচরণ যখন সক্ষম করে is_transparentতুলনা ফাংশন বস্তুর করা 23.2.4 [associative.reqmts] অনুচ্ছেদ 13. ডিফল্ট তুলনা ফাংশন বস্তু হয় অনুযায়ী সংজ্ঞায়িত করা হয় std::less<Key>23.4.2 [associative.map.syn] এবং 23.4 অনুযায়ী। 3 [এসোসিয়েটিভ.সেট.সাইন]। 20.10.5 [তুলনা] অনুচ্ছেদ অনুযায়ী 4 এর সাধারণ টেম্পলেট কোনও নেস্টেড ধরণের সংজ্ঞা std::less<...>দেয় নাis_transparent তবে std::less<void>বিশেষায়িতকরণটি করে। এটি হ'ল না, আপনি ডিফল্টরূপে স্বচ্ছ অপারেটর পাবেন না।
ডায়েটমার কাহল

নামকরণের জন্য আপনার কি কোনও ধারণা আছে? মানে কেন is_transparent?
প্লাজম্যাসেল

আপনি একটি "কংক্রিট উদাহরণ যেখানে এটি দরকারী" চান? এখানে আমার ব্যবহারের
কেসটি রয়েছে

19

নিম্নলিখিত n3657 থেকে সমস্ত অনুলিপি-পাস্তা হয় ।

প্র: তুলনামূলক "স্বচ্ছ" করার উদ্দেশ্য কী?

উ: সংঘবদ্ধ কন্টেইনার লুকআপ ফাংশনগুলি (সন্ধান করুন, নিম্ন_বাউন্ড, আপার_বাউন্ড, সমান_আরঞ্জ) কেবল কী_আর টাইপ যুক্তি গ্রহণ করে, ব্যবহারকারীদের অনুসন্ধানের জন্য কী_ টাইপের কোনও অবজেক্ট (স্পষ্ট বা স্পষ্টতই) তৈরি করতে হবে। এটি ব্যয়বহুল হতে পারে, যেমন তুলনামূলক ফাংশন কেবলমাত্র অবজেক্টের একটি ক্ষেত্রের দিকে তাকালে কোনও সেটটিতে অনুসন্ধানের জন্য একটি বৃহত অবজেক্ট তৈরি করা। ব্যবহারকারীদের মধ্যে অন্যান্য ধরণের কী_ টাইপের সাথে তুলনীয়, যা ব্যবহার করে অনুসন্ধান করতে সক্ষম হবার প্রবণতা রয়েছে।

প্র: এটি কোন সমস্যার সমাধান করে

উ: এলডাব্লুজির নীচের মত কোড সম্পর্কে উদ্বেগ ছিল:

std::set<std::string> s = /* ... */;
s.find("key");

সি ++ 11 এ এটি একটি একক std :: স্ট্রিংটি অস্থায়ীভাবে তৈরি করবে এবং তারপরে কীটি অনুসন্ধানের জন্য এটি উপাদানগুলির সাথে তুলনা করবে।

N3465 দ্বারা প্রস্তাবিত পরিবর্তনের সাথে std :: set :: Find () ফাংশনটি একটি বেআইনী টেমপ্লেট হবে যা কনস্টের চারটি * এর সাথে তুলনামূলক ফাংশনটি পাস করবে, std :: কম, যা একটি স্টাড :: স্ট্রিং অস্থায়ী জন্য নির্মাণ করবে প্রতিটি তুলনা। এলডাব্লুজি এই পারফরম্যান্স সমস্যাটিকে একটি গুরুতর সমস্যা বলে মনে করেছে। টেমপ্লেট সন্ধান () ফাংশনটি পয়েন্টারগুলির ধারকটিতে NULL সন্ধান করাও আটকাতে পারে, যার কারণে আগের বৈধ কোডটি আর সংকলন করতে পারে না, তবে এটি নিঃশব্দ পারফরম্যান্স রিগ্রেশনের চেয়ে কম গুরুতর সমস্যা হিসাবে দেখা হয়েছিল

প্র। স্ট্যান্ডার্ড পাত্রে কীভাবে কাজ করে তা এই পরিবর্তন করে

উ: এই প্রস্তাবটি সদস্য ফাংশন টেমপ্লেটগুলি সহ লুচিং সদস্য ফাংশনগুলিকে ওভারলোড করে সাহসী পাত্রে পরিবর্তন করে। ভাষার কোনও পরিবর্তন নেই।

প্র। সুতরাং ডিফল্ট সেট তার অনুসন্ধান, গণনা ইত্যাদি সদস্যকে হারিয়ে ফেলবে

উ: প্রায় সমস্ত বিদ্যমান সি ++ 11 কোডটি প্রভাবিত হয়নি কারণ সদস্য সিদ্ধিগুলি উপস্থিত নেই যদি না নতুন সি ++ 14 লাইব্রেরি বৈশিষ্ট্যগুলি তুলনা ফাংশন হিসাবে ব্যবহার না করা হয়।

ইয়াককে উদ্ধৃত করা ,

সি ++ ১৪-এ, স্ট্যান্ড :: সেট :: সন্ধান করুন একটি টেম্পলেট ফাংশন যদি তুলনা করুন: হয়_আপনি বিদ্যমান থাকে। আপনি যে ধরণের পাস করেন তা কী হওয়ার দরকার নেই, কেবল আপনার তুলকের তুলনায় সমান।

এবং n3657,

২৩.২.৪ এ অনুচ্ছেদে ১৩ যোগ করুন [এসোসিয়েটিভ.আরকিমিটস]: সদস্য ফাংশন টেম্পলেটগুলি সন্ধান করে, নিম্ন_বাউন্ড, আপার_বাউন্ড এবং ইক্যুয়াল_রেঞ্জ ওভারলোড রেজোলিউশনে অংশ নেবে না যদি না টাইপ করুন তুলনা :: is_transpants অস্তিত্ব না থাকে।

n3421 "স্বচ্ছ অপারেটর ফান্টাক্টর" এর একটি উদাহরণ সরবরাহ করে ।

সম্পূর্ণ কোড এখানে


1
না std::set<std::string>আসলে "ক্ষণস্থায়ী থেকে উপকৃত char const *, মাধ্যমে" অথবা আপনি একটি করতে হবে না std::set<std::string, std::less<>>?
কেরেক এসবি

@ কেরেক আমার ধারণা আমি ভুল না হলে "চর কনস্ট * কে" পাস করার বিষয়টি তারা এড়াতে চাইছিল। শব্দটি দেখুন:With the change proposed by N3465 the std::set::find() function would be an unconstrained template which would pass the const char* through to the comparator function, std::less<std::string>, which would construct a std::string temporary for every comparison. The LWG considered this performance problem to be a serious issue.

আপনার অনুচ্ছেদ 13 এর উদ্ধৃতি এবং আমার বিপরীতে বলেছেন: "যদি না টাইপটি উপস্থিত থাকে / উপস্থিত না থাকে" ... ?!
কেরেক এসবি

4
@ কেরেকএসবি, এটি আমার দোষ, এন 65657 "বলার অপেক্ষা রাখে না" বলে মনে করা হয়েছিল কিন্তু আমি লিখেছিলাম "বিদ্যমান নেই" ... এটি শেষ মুহুর্তে লেখা একটি দেরি কাগজ ছিল। খসড়া মানটি সঠিক।
জোনাথন ওয়েকেলি

3
হ্যাঁ, আমি আসলে যা বলছিলাম তা না বলার অর্থটি স্পষ্টভাবে পরিষ্কার হতে পারে :)
জনাথন ওয়েকেলি

7

স্টিফান টি লাভভেজ এমন সমস্যা সম্পর্কে কথা বলছেন যেখানে সংকলক টেম্পোরারি তৈরি করে চলেছে, এবং স্বচ্ছ অপারেটর ফ্যান্ট্যাক্টারের প্রস্তাব কীভাবে এটি সি ++ 1 এ সমাধান করবে?

GoingNative 2013 - সংকলককে সহায়তা করবেন না (প্রায় ঘন্টা সময়)

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