কোনও রূপান্তর অপারেটরের এই ওভারলোডটি কেন বেছে নেওয়া হয়েছে?


27

নিম্নলিখিত কোড বিবেচনা করুন ।

struct any
{
    template <typename T>
    operator T &&() const;

    template <typename T>
    operator T &() const;
};
int main()
{
    int a = any{};
}

এখানে ওভারলোড রেজোলিউশন দ্বারা দ্বিতীয় রূপান্তর অপারেটরটি বেছে নেওয়া হয়েছে। কেন?

যতদুর আমি এটা বুঝতে হিসাবে, দুই অপারেটরে অনুমিত হয় operator int &&() constএবং operator int &() constযথাক্রমে। উভয়ই কার্যক্ষম ফাংশনের সেটে রয়েছে। [Over.match.best] এর মাধ্যমে পড়া আমার উত্তরটি কেন আরও ভাল তা বুঝতে সাহায্য করে না।

পরের কাজটি কেন আগের চেয়ে ভাল?


আমি একটি সাধারণ বিড়াল এবং আমি বলব এটি অবশ্যই অন্য একবার হবে অন্যটির পরিচিতিটি সি ++ 11 এ একটি ব্রেকিং পরিবর্তন হতে পারে। এটা কোথাও স্ট্যান্ডার্ড হবে। ভাল প্রশ্ন যদিও, একটি upvote আছে। : (দৃষ্টি আকর্ষণ করছি বিশেষজ্ঞদের যদি এই মন্তব্যটি hogwash তাহলে দয়া করে আমাকে বলবেন!)
বৎশেবা

3
এফডাব্লুআইডাব্লু, template <typename T> operator T &&() const &&; template <typename T> operator T &() const &;এটি প্রথমটিকে কল করতে পারে।
নাথান অলিভার

5
@ লাইটনেসেসেস উইথমোনিকা কনভার্সন অপারেটররা এটির অনুমতি দেয় অন্যথায় একাধিক রূপান্তর অপারেটর রাখার উপায় নেই।
নাথান অলিভার

1
@ বাথশেবা আমি এর কারণ মনে করি না। এটি বলার মতো যে মুভ কনস্ট্রাক্টররা কখনই ওভারলোড রেজোলিউশন দ্বারা নির্বাচন করতে পারবেন না কারণ এটি একটি ব্রেকিং পরিবর্তন হবে। আপনি যদি কোনও মুভ কনস্ট্রাক্টর লিখেন তবে আপনি নিজের সংজ্ঞাটি সেই সংজ্ঞা অনুসারে "ভাঙ্গা" হয়ে বেছে নিচ্ছেন।
ব্রায়ান

1
@ লাইটনেসেসেসিথমোনিকা যেভাবে আমি এটি সরাসরি আমার মাথায় রাখি তা হ'ল আমি ফাংশনের নাম হিসাবে ফিরতি টাইপটিকেই বিবেচনা করি। বিভিন্ন প্রকারের সমান বিভিন্ন নাম সমান সাফল্য :)
নাথান ওলিভার

উত্তর:


13

যে রূপান্তর অপারেটরটি প্রত্যাবর্তন করা T&হয় সেটিকে অগ্রাধিকার দেওয়া হয় কারণ এটি রূপান্তরকারী অপারেটরের চেয়ে বেশি বিশেষায়িত T&&

সি ++ 17 দেখুন (টেম্পেডাক্ট. পার্টিশিয়াল] / (3.2):

কোনও রূপান্তর ফাংশনে কল করার প্রসঙ্গে, রূপান্তর ফাংশন টেম্পলেটগুলির ফেরতের প্রকারগুলি ব্যবহৃত হয়।

এবং / 9:

যদি, প্রদত্ত প্রকারের জন্য, উভয় দিক থেকে কর্তন সফল হয় (উদাহরণস্বরূপ, ধরণগুলি উপরে বর্ণিত রূপান্তরের পরে অভিন্ন) এবং উভয়ই Pএবং Aরেফারেন্স ধরণের ছিল (উপরে বর্ণিত ধরণের সাথে প্রতিস্থাপনের আগে): - আর্গুমেন্ট টেম্পলেট থেকে টাইপ হলে একটি মূল্যবান রেফারেন্স ছিল এবং পরামিতি টেমপ্লেট থেকে প্রকারটি ছিল না, প্যারামিটারের ধরনটি কমপক্ষে যুক্তির ধরণের হিসাবে বিশেষ হিসাবে বিবেচিত হয় না; ...


12

ছাড়ানো রিটার্ন মান রূপান্তর অপারেটররা কিছুটা অদ্ভুত। তবে মূল ধারণাটি হ'ল এটি কোনটি ব্যবহৃত হয় তা চয়ন করার জন্য এটি একটি ফাংশন প্যারামিটারের মতো কাজ করে।

আর যখন মধ্যবর্তী সিদ্ধান্ত T&&এবং জমিদার রেজল্যুশন নিয়ম ধিক্কার জানাই। এটি অনুমোদিত:T&T&

template<class T>
void f( T&& ) { std::cout << "rvalue"; }
template<class T>
void f( T& ) { std::cout << "lvalue"; }

কাজ করতে. T&&একটি লভালুর বিপরীতে মিলতে পারে, তবে যখন লভালু এবং সর্বজনীন রেফারেন্স ওভারলোড উভয় উপলব্ধ থাকে তবে লভালুটি পছন্দ হয়।

রূপান্তর অপারেটরগুলির সঠিক সেট সম্ভবত:

template <typename T>
operator T&&() &&;

template <typename T>
operator T &() const; // maybe &

অথবা এমনকি

template <typename T>
operator T() &&;

template <typename T>
operator T &() const; // maybe &

আপনাকে দংশন থেকে ব্যর্থ আজীবন প্রসার রোধ করতে।

অর্ডার নির্ধারণের জন্য ব্যবহৃত প্রকারগুলি আংশিক অর্ডারিংয়ের প্রেক্ষাপটে নির্ভর করে:

[স্নিপ]

(৩.২) কোনও রূপান্তর ফাংশনে কল করার প্রসঙ্গে, রূপান্তর ফাংশন টেম্পলেটগুলির ফেরতের প্রকারগুলি ব্যবহৃত হয়।

যার পরে ওভারলোডগুলি বাছাই করার সময় "আরও বিশেষায়িত" নিয়মের উপর নির্ভর করে শেষ হয়:

(৯.১) যদি আর্গুমেন্ট টেমপ্লেট থেকে প্রকারটি একটি লভ্যালু রেফারেন্স এবং প্যারামিটার টেম্পলেট থেকে প্রকারটি না হয় তবে প্যারামিটারের ধরনটি কমপক্ষে যুক্তির ধরণের হিসাবে বিশেষ হিসাবে বিবেচিত হয় না; অন্যথায়,

এইভাবে operator T&&কমপক্ষে হিসাবে বিশেষায়িত নয় operator T&, এর মধ্যে কোনও নিয়ম রাষ্ট্র operator T&কমপক্ষে হিসাবে বিশেষায়িত নয় operator T&&, তাই এর operator T&চেয়ে বেশি বিশেষায়িত operator T&&

আরও বিশেষায়িত টেম্পলেটগুলি কম ওভারলোড রেজোলিউশন জিতেছে, সমস্ত কিছু সমান।


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

4

আমরা একটি intথেকে একটি আরম্ভ করার চেষ্টা করছি any। এটির জন্য প্রক্রিয়া:

  1. আমরা যেটা করতে পারি তার সমস্ত উপায় বের করুন। তা হচ্ছে, আমাদের সকল প্রার্থী নির্ধারণ করুন। এগুলি intস্ট্যান্ডার্ড রূপান্তর সিকোয়েন্সের ( [over.match.conv] ) মাধ্যমে রূপান্তর করতে পারে এমন স্পষ্টত রূপান্তর রূপান্তর ফাংশন থেকে আসে । বিভাগে এই বাক্যাংশটি রয়েছে:

    "রেফারেন্স" -এর প্রত্যাবর্তনকারী কোনও রূপান্তর ফাংশনে কল Xহ'ল প্রকারের আভাস X, এবং এই জাতীয় রূপান্তর ফাংশন তাই Xপ্রার্থী ফাংশন নির্বাচন করার এই প্রক্রিয়াটির জন্য ফলন হিসাবে বিবেচিত হয় ।

  2. সেরা প্রার্থী চয়ন করুন।

পদক্ষেপ 1 পরে, আমাদের দুটি প্রার্থী রয়েছে। operator int&() constএবং operator int&&() const, উভয়ই intপ্রার্থীর কার্যকারিতা বাছাইয়ের উদ্দেশ্যে ফলন হিসাবে বিবেচিত হয় । ফলন সেরা প্রার্থী কোনটি int?

আমাদের কাছে একটি টাইব্রেকার রয়েছে যা মূল্যের রেফারেন্সগুলিতে ( [over.ics.rank] /3.2.3 ) এর সাথে লভালিউ রেফারেন্সকে পছন্দ করে । যদিও আমরা এখানে আসলে একটি রেফারেন্সকে বেঁধে রাখছি না, এবং উদাহরণটি কিছুটা উল্টানো রয়েছে - এটি সেই ক্ষেত্রে যেখানে প্যারামিটারটি একটি লভালিউ বনাম সমমূল্য রেফারেন্স।

যদি এটি প্রযোজ্য না হয়, তবে আমরা আরও বিশেষায়িত ফাংশন টেম্পলেটটিকে প্রাধান্য দেওয়ার জন্য [ওভার.ম্যাচ.বেস্ট] / ২.৫ টাইব্রেকারে পড়ি

সাধারণত বললে, থাম্বের নিয়ম আরও নির্দিষ্ট রূপান্তর সেরা ম্যাচ হয় the লভ্যালু রেফারেন্স রূপান্তর ফাংশন ফরওয়ার্ডিং রেফারেন্স রূপান্তর ফাংশনের চেয়ে বেশি নির্দিষ্ট, তাই এটি পছন্দসই। সেখানে প্রায় কিছুই নেই intআমরা আরম্ভের করছি যে rvalue প্রয়োজন (আমরা পরিবর্তে একটি আরম্ভের ছিল জুলুম int&&, তারপর operator T&() constএকটি প্রার্থী হতো না)।


৩.২.৩ আসলে T&&জিততে বলে? আহা, তবে আমাদের কোনও মূল্যায়ন আবদ্ধ হচ্ছে না। আমরা নাকি? আমাদের প্রার্থীদের বাছাই করার সময় কিছু শব্দ অবশ্যই সংজ্ঞা দিয়েছিল যে আমরা কীভাবে পেয়েছি int&এবং int&&এটি কি বাধ্যতামূলক ছিল?
ইয়াক্ক - অ্যাডাম নেভ্রামুমন্ট

@ ইয়াক্ক-অ্যাডামনেভ্র্যামন্ট নং, যে কোনও ব্যক্তি মূল্য সংক্রান্ত রেফারেন্সগুলিতে পছন্দ করে। আমি মনে করি এটি সম্ভবত ভুল বিভাগ, এবং "আরও বিশেষায়িত" টাইব্রেকার হ'ল সঠিক।
ব্যারি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.