ফাংশন আর্গুমেন্ট হিসাবে কেন amb Why অস্পষ্টতার দিকে পরিচালিত করে না?


20

এই কোডটি বিবেচনা করুন:

#include <vector>
#include <iostream>

enum class A
{
  X, Y
};

struct Test
{
  Test(const std::vector<double>&, const std::vector<int>& = {}, A = A::X)
  { std::cout << "vector overload" << std::endl; }

  Test(const std::vector<double>&, int, A = A::X)
  { std::cout << "int overload" << std::endl; }
};

int main()
{
  std::vector<double> v;
  Test t1(v);
  Test t2(v, {}, A::X);
}

https://godbolt.org/z/Gc_w8i

এই মুদ্রণ:

vector overload
int overload

অস্পষ্ট ওভারলোড রেজোলিউশনের কারণে কেন এটি সংকলন ত্রুটি তৈরি করে না? যদি দ্বিতীয় কনস্ট্রাক্টর সরানো হয় তবে আমরা vector overloadদু'বার পাই । কীভাবে / কোন মেট্রিকের তুলনায় intদ্ব্যর্থহীনভাবে আরও ভাল ম্যাচ হয় ?{}std::vector<int>

কনস্ট্রাক্টর স্বাক্ষরটি অবশ্যই আরও ছাঁটাই করা যেতে পারে, তবে আমি কেবল কোডের একটি সমতুল অংশ দ্বারা চালিত হয়েছি এবং নিশ্চিত করতে চাই যে এই প্রশ্নের জন্য গুরুত্বপূর্ণ কোনও কিছুই হারিয়েছে না।


যদি আমি কোডের {}ব্লক হিসাবে সুস্পষ্টভাবে স্মরণ করি , 0 কে ভেরিয়েবলগুলিকে বরাদ্দ করি - উদাহরণস্বরূপ: কনট চর x = {}; 0 (নাল চর) এ সেট করা হয়, আন্ত ইত্যাদি ইত্যাদির জন্য একই
সেটি

2
@ শেটি এটি {}নির্দিষ্ট কিছু ক্ষেত্রে কার্যকরভাবে কার্যকর করে তবে এটি সাধারণত সঠিক হয় না (শুরুতে, std::vector<int> x = {};কাজ করে, std::vector <int> x = 0;না করে)। এটি " {}শূন্যকে নির্ধারণ করে " এর মতো সহজ নয় ।
ম্যাক্স ল্যাঙ্গোফ

ঠিক আছে, এটি এত সহজ নয়, তবে এটি এখনও শূন্যকে বরাদ্দ করেছে - আমি ভাবলাম যে এই বেভিওরটি বেশ বিভ্রান্তিকর এবং সত্যই ব্যবহার করা উচিত নয়
Seti

2
@ শেটি struct A { int x = 5; }; A a = {};কোনও অর্থে শূন্য বরাদ্দ করে না, এটি একটি Aদিয়ে তৈরি করে a.x = 5। এটি এর বিপরীত A a = { 0 };, যা a.x0 থেকে আরম্ভ করে The শূন্যটি অন্তর্নিহিত নয় {}, প্রতিটি প্রকারটি কীভাবে ডিফল্ট-নির্মিত বা মান-প্রাথমিককরণ হয় তা সহজাত । দেখুন এখানে , এখানে এবং এখানে
ম্যাক্স ল্যাঙ্গোফ

আমি এখনও মনে করি যে ডিফল্ট-নির্মিত মানটি বিভ্রান্তিমূলক হয় (আপনার আচরণটি পরীক্ষা করা বা সারাক্ষণ অনেক বেশি জ্ঞান রাখা দরকার)
সেতি

উত্তর:


12

এটি [over.ics.list] এ , জোর আমার

6 অন্যথায়, যদি প্যারামিটারটি একটি অ-সমষ্টিগত ক্লাস এক্স এবং ওভারলোড রেজোলিউশন প্রতি [ওভার.ম্যাচ.লিস্ট] এক্স এর একক সেরা কনস্ট্রাক্টর সি বেছে নেয় এক্স প্রকারের একটি অবজেক্টের আরম্ভ করার জন্য আর্গুমেন্ট আরম্ভকারী তালিকা থেকে:

  • যদি সি কোনও প্রাথমিককরণ-তালিকা নির্মাণকারী না হয় এবং প্রারম্ভিক তালিকায় সিভি ইউ টাইপের একটি একক উপাদান থাকে , যেখানে ইউ এক্স হয় বা এক্স থেকে প্রাপ্ত একটি শ্রেণি থাকে তবে অন্তর্নিহিত রূপান্তর ক্রমের সাথে ইউ এক্স হলে এক্সটাক্ট ম্যাচ র‌্যাঙ্ক থাকে, অথবা রূপান্তর র‌্যাঙ্ক থাকলে ইউ এক্স থেকে প্রাপ্ত is

  • অন্যথায়, অন্তর্নিহিত রূপান্তর ক্রমটি দ্বিতীয় স্ট্যান্ডার্ড রূপান্তর ক্রমটি একটি পরিচয় রূপান্তর সহ একটি ব্যবহারকারী-সংজ্ঞায়িত রূপান্তর ক্রম।

9 অন্যথায়, যদি প্যারামিটারের ধরণটি শ্রেণি না হয়:

  • [...]

  • যদি প্রাথমিকের তালিকার কোনও উপাদান না থাকে তবে অন্তর্নিহিত রূপান্তর ক্রমটি পরিচয় রূপান্তর। [উদাহরণ:

    void f(int);
    f( { } ); // OK: identity conversion
    

    শেষ উদাহরণ]

std::vectorকন্সট্রাকটর এবং গাঢ় এটি একটি ব্যবহারকারী সংজ্ঞায়িত converison ঘোষিত বুলেট দ্বারা সক্রিয়া করা হয়। এদিকে, intএকজনের জন্য এটি পরিচয় রূপান্তর, সুতরাং এটি প্রথম ক্যাটারের র‌্যাঙ্ককে ট্রাম্প করে।


হ্যাঁ, সঠিক বলে মনে হচ্ছে
কলম্বো

এই পরিস্থিতিটি স্পষ্টভাবে স্ট্যান্ডার্ড হিসাবে বিবেচিত হয় তা দেখতে আকর্ষণীয়। আমি সত্যিই এটি অস্পষ্ট বলে আশা করব (এবং দেখে মনে হচ্ছে এটি সহজেই সেইভাবে নির্দিষ্ট করা যেতে পারে)। আমি আপনার শেষ বাক্যে যুক্তিটি অনুসরণ করতে পারি না - 0এতে টাইপ intকিন্তু টাইপ নেই std::vector<int>, এটি কীভাবে "" টাইপড "প্রকৃতির প্রতিচ্ছবি {}?
ম্যাক্স ল্যাংফোফ

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

অংশটি পরিষ্কার। আমি একজন ব্যবহারকারী-সংজ্ঞায়িত রূপান্তরকরণের প্রয়োজনে অবাক হয়েছি std::vector<int>। যেমনটি আপনি বলেছিলেন, আমি প্রত্যাশা করেছি যে "প্যারামিটারের ধরণটি আর্গুমেন্টের ধরণ কী হবে তা স্থির করে" এবং একটি {}"প্রকারের" (যাতে কথা বলার জন্য) std::vector<int>আরম্ভ করার জন্য (অ-পরিচয়) রূপান্তর প্রয়োজন হবে না std::vector<int>। স্ট্যান্ডার্ড স্পষ্টতই বলে যে এটি করে, তাই এটি, তবে এটি আমার কাছে বোধগম্য নয়। (মনে মনে, আমি তর্ক করছি না যে আপনি বা মানটি ভুল, কেবল আমার মানসিক মডেলগুলির সাথে এটি পুনর্মিলন করার চেষ্টা করছেন।)
ম্যাক্স ল্যাংগোফ

ঠিক আছে, সম্পাদনাটি আমি আশা করি এমন রেজোলিউশন ছিল না, তবে যথেষ্ট ছিল। : ডি আপনার সময়ের জন্য ধন্যবাদ!
সর্বোচ্চ ল্যাঙ্গোফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.