প্রত্যাবর্তনের সময় অন্তর্নিহিত রূপান্তর অনুমোদিত নয়


21
#include <optional>

bool f() {
  std::optional<int> opt;
  return opt;
}

সংকলন করে না: 'return': cannot convert from 'std::optional<int>' to 'bool'

পরামর্শের রেফারেন্সটি আমি ব্যাখ্যাটি আবিষ্কার করার জন্য ভাবতাম, তবে এটি ঠিক হওয়া উচিত বলে আমি এটি পড়েছি।

অন্তর্ভুক্ত রূপান্তরগুলি সম্পাদিত হয় যখনই কোনও প্রকারের টি 1 এর একটি অভিব্যক্তি প্রসঙ্গে ব্যবহার করা হয় যা সেই ধরণেরটি গ্রহণ করে না, তবে কিছু অন্য ধরণের টি 2 গ্রহণ করে; নির্দিষ্টভাবে:

  • যখন টি 2 দিয়ে প্যারামিটার হিসাবে ঘোষিত কোনও ফাংশন কল করার সময় অভিব্যক্তিটি আর্গুমেন্ট হিসাবে ব্যবহৃত হয়;
  • যখন অভিব্যক্তিটি অপারেটরের সাথে অপারেন্ড হিসাবে ব্যবহৃত হয় যা টি 2 আশা করে;
  • টি 2 রিটার্ন করে একটি ফাংশনে রিটার্ন স্টেটমেন্ট সহ টি 2 টাইপের নতুন কোনও বস্তুর সূচনা করার সময়;
  • যখন অভিব্যক্তিটি একটি স্যুইচ স্টেটমেন্টে ব্যবহৃত হয় (টি 2 অবিচ্ছেদ্য টাইপ);
  • যখন অভিব্যক্তিটি যদি একটি if স্টেটমেন্ট বা লুপে ব্যবহৃত হয় (টি 2 বুল হয়)।

7
" অন্তর্নিহিত ধর্মান্তর সঞ্চালিত হয়" , কিন্তু operator bool()এর std::optionalরয়েছে explicit
জারোড 42

উত্তর:


22

std::optionalসুস্পষ্টভাবে রূপান্তর করার কোনও সুবিধা নেই bool। (অন্তর্নিহিত রূপান্তরগুলিকে মঞ্জুরি দেওয়া boolসাধারণত একটি খারাপ ধারণা হিসাবে বিবেচিত হয়, যেহেতু boolএকটি অবিচ্ছেদ্য ধরণের তাই এমন int i = optকোনও কিছু সংকলন করে এবং সম্পূর্ণরূপে ভুল কাজটি করে))

std::optional নেই একটি "প্রাসঙ্গিক রূপান্তর" bool আছে, যার মধ্যে সংজ্ঞা একটি ঢালাই অপারেটর অনুরূপ: explicit operator bool()। এটি অন্তর্নিহিত রূপান্তরগুলির জন্য ব্যবহার করা যাবে না; এটি কেবলমাত্র নির্দিষ্ট কিছু ক্ষেত্রে প্রযোজ্য যেখানে প্রত্যাশিত "প্রসঙ্গ" একটি বুলিয়ান, যেমন-যদি-স্টেটমেন্টের শর্ত থাকে।

আপনি কি চান opt.has_value()


4

সি ++ ডক্স থেকে :

প্রকারের একটি বস্তু যখন ঐচ্ছিক <টি> হয় বিষয়গতভাবে রূপান্তরিত bool, যাও, রূপান্তর আয় সত্য বস্তু যদি এটি একটি মান ধারণ করে না একটি মান এবং মিথ্যা থাকে।

প্রাসঙ্গিক রূপান্তর সম্পর্কে এখানে পড়ুন :

নিম্নলিখিত প্রসঙ্গে, টাইপ বুলের প্রত্যাশা করা হয় এবং ঘোষণার বুল টি (ঙ) যদি অন্তর্নিহিত রূপান্তর সম্পাদিত হয়; সুগঠিত (এটি, একটি সুস্পষ্ট রূপান্তর ফাংশন যেমন সুস্পষ্ট টি :: অপারেটর বুল () কনস্ট; বিবেচিত)। এ জাতীয় অভিব্যক্তি ই প্রাসঙ্গিকভাবে বোলে রূপান্তরিত হবে বলে জানা গেছে।

  • নিয়ন্ত্রণকারী এক্সপ্রেশন যদি, যখন, এর জন্য;
  • অন্তর্নির্মিত লজিকাল অপারেটরগুলির অপারেশনগুলি!, &&& ||
  • শর্তসাপেক্ষ অপারেটরের প্রথম অপারেন্ড?:;
  • একটি স্ট্যাটিক_সেটর ঘোষণায় শিকারী;
  • একটি নোসেপ্ট স্পেসিফায়ারে এক্সপ্রেশন;
  • স্পষ্ট স্পেসিফায়ারে এক্সপ্রেশন;

আপনি নিম্নলিখিত হ্যাক করতে পারেন:

bool f() {
    std::optional<int> opt;
    return opt || false;
}

কারণ অন্তর্নিহিত লজিকাল অপারেটরগুলির ক্ষেত্রে প্রাসঙ্গিক রূপান্তর ঘটে থাকে, তবে প্রাসঙ্গিক রূপান্তরটিতে বিবৃতি অন্তর্ভুক্ত হয় নাreturn এবং std::optionalনিজেই এতে অন্তর্নিহিত রূপান্তর থাকে নাbool

অতএব, এটি ব্যবহার করা সবচেয়ে ভাল হবে std::optional<T>::has_value:

bool f() {
    std::optional<int> opt;
    return opt.has_value();
}

কি return {opt}? বাreturn bool{opt};
দারুনে

3
@दरুন return {opt};কাজ করবে না return static_cast<bool>(opt);বা return bool{opt};কাজ করবে। তবে এটির has_valueসদস্য ফাংশনটি ব্যবহার করার পরামর্শ দেওয়া হয়েছে কারণ এটি আপনি যা করতে চান তার প্রকৃত উদ্দেশ্যটি দেখায়
নটক্র্যাকার

বা বিখ্যাত return !!pot;হ্যাক ( has_valueআরও ভাল)
এলএফ

1

এর কারণ হল যে, স্ট্যান্ড :: এর বুলের বিকল্পের অন্তর্নিহিত সংক্ষিপ্তসারটি সমর্থনযোগ্য নয়: https://en.cppreferences.com/w/cpp/utility/optional/operator_bool

কনস্টেক্সপ্রিফ স্পষ্টত অপারেটর বুল () কনস্টেক্স নোসেকসেপ্ট;

আপনাকে স্পষ্টভাবে বিলে রূপান্তর করতে হবে bool(opt)বা কেবল opt.has_value()পরিবর্তে ব্যবহার করতে হবে।


বুল {অপ্ট well পাশাপাশি কাজ করে এবং
বুল

1

এটি সত্যই অন্তর্নিহিত রূপান্তর সম্পর্কে নয়, এটি আরম্ভের ধরণ সম্পর্কে।

Optionচ্ছিক যা আছে তা হল একটি স্পষ্ট রূপান্তর ফাংশন, অর্থাত্

explicit operator bool() const; 

এন 4849 [শ্রেণী.কনভ.ফ্যাক্ট] / পি 2 থেকে

কোনও রূপান্তর ফাংশনটি সুস্পষ্ট (9.2.2) হতে পারে, সেক্ষেত্রে এটি কেবল প্রত্যক্ষ-আরম্ভের জন্য ব্যবহারকারী-সংজ্ঞায়িত রূপান্তর হিসাবে বিবেচিত হয়।

উপরের অর্থ হ'ল এই কেসগুলি রূপান্তর ফাংশনটি ব্যবহার করবে: [dcl.init] / p16

সূচনা যা ঘটে (১ 16.১) - একটি প্রাথমিক-সংক্ষিপ্ত এক্সপ্রেশন-তালিকা বা ব্রেসড-থ্রি-তালিকা, (১ 16.২) - একটি স্ট্যাটিক_কাস্ট এক্সপ্রেশনে (১.6.২) - .6..6.১.৮), (১ function.৪) - একটি কার্যকরী স্বরলিপি ধরণের রূপান্তর (.6..6.১.৩), এবং (১.5.৫) - একটি শর্তের ব্রেসড-আর-তালিকা ফর্মকে সরাসরি-সূচনা বলে।

তবে, এই ক্ষেত্রেগুলি রূপান্তর ফাংশনটি ব্যবহার করবে না: [dcl.init] / p15

সূচনাটি যা ব্রেস-বা-সম-ইনিশিয়ালাইজার বা শর্তের আকারে (8.5), পাশাপাশি যুক্তি পাস, ফাংশন রিটার্ন, একটি ব্যতিক্রম (14.2) নিক্ষেপ করে, একটি ব্যতিক্রম (14.4) পরিচালনা করে এবং সদস্য আরম্ভ হয় (9.4.1), কপি-ইনিশিয়েশন বলা হয়।

প্রশ্নের উদাহরণটি অনুলিপিকরণের অনুলিপি ক্ষেত্রে আসে এবং optionচ্ছিক রূপান্তর ফাংশন ব্যবহার করে না।

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