সি ++ ডিক্লাইপ এবং প্রথম বন্ধনী - কেন?


32

বিষয়টি আগেও আলোচনা করা হয়েছিল , তবে এটি কোনও সদৃশ নয়।

যখন কেউ মধ্যে পার্থক্য সম্পর্কে জিজ্ঞেস করে decltype(a)এবং decltype((a))স্বাভাবিক উত্তর - aএকটি পরিবর্তনশীল (a)একটি অভিব্যক্তি। আমি এই উত্তরটি সন্তুষ্ট নয়।

প্রথমত, aপাশাপাশি একটি প্রকাশ। প্রাথমিক প্রকাশের বিকল্পগুলির মধ্যে অন্যদের মধ্যে অন্তর্ভুক্ত রয়েছে -

  • (প্রকাশ)
  • আইডি প্রকাশ

আরও গুরুত্বপূর্ণ, ডিক্লাইপ টাইপের জন্য শব্দবন্ধগুলি খুব বন্ধুত্বকে খুব খুব স্পষ্টভাবে বিবেচনা করে :

For an expression e, the type denoted by decltype(e) is defined as follows:
(1.1)  if e is an unparenthesized id-expression naming a structured binding, ...
(1.2)  otherwise, if e is an unparenthesized id-expression naming a non-type template-parameter, ...
(1.3)  otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access, ...
(1.4)  otherwise, ...

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


2
"সাধারন উত্তরটি হ'ল - একটি একটি পরিবর্তনশীল, (ক) একটি অভিব্যক্তি" তারা যা বোঝায় তা হল " (a)একটি অভিব্যক্তি, এবং aএটি একটি প্রকাশ এবং একটি পরিবর্তনশীল"।
হলিব্ল্যাকগেট

উত্তর:


18

এটি কোনও তদারকি নয়। এটি আকর্ষণীয়, ডেকলটাইপ এবং অটোতে (পুনর্বিবেচনা 4) (এন 1705 = 04-0145) এ একটি বিবৃতি রয়েছে:

ডিক্লিটপ বিধিগুলি এখন স্পষ্টভাবে decltype((e)) == decltype(e)জানিয়েছে যে (EWG দ্বারা প্রস্তাবিত)।

তবে ডেকলটাইপে (পুনর্বিবেচনা)): প্রস্তাবিত শব্দবন্ধ (N2115 = 06-018) এর মধ্যে একটি পরিবর্তন রয়েছে

ডেকলটাইপের অভ্যন্তরে প্যারেন্টসাইজড-এক্সপ্রেশনটিকে একটি হিসাবে বিবেচনা করা হয় না id-expression

শব্দের কোনও যৌক্তিকতা নেই, তবে আমি মনে করি এটি কিছুটা ভিন্ন সিনট্যাক্স ব্যবহার করে ডিক্লাইপ প্রকারের প্রসারিত, অন্য কথায়, এই কেসগুলি পৃথক করার উদ্দেশ্যে এটি করা হয়েছিল।

এর জন্য ব্যবহার সি ++ খসড়া 9.2.8.4 এ দেখানো হয়েছে:

const int&& foo();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1 = 17;        // type is const int&&
decltype(i) x2;                 // type is int
decltype(a->x) x3;              // type is double
decltype((a->x)) x4 = x3;       // type is const double&

আসলেই কী আকর্ষণীয়, তা কীভাবে returnবিবৃতিতে কাজ করে :

decltype(auto) f()
{
    int i{ 0 };
    return (i);
}

আমার ভিজ্যুয়াল স্টুডিও 2019 আমাকে রিলান্ড্যান্ট প্রথম বন্ধনী অপসারণের পরামর্শ দেয়, তবে বাস্তবে তারা পরিবর্তিত হয় decltype((i))যা int&কোনও স্থানীয় ভেরিয়েবলের রেফারেন্স ফিরিয়ে দেওয়ার কারণে এটির পরিবর্তনের মান পরিবর্তন করে।


মূলটি পিন-পয়েন্ট দেখানোর জন্য আপনাকে ধন্যবাদ! ডিক্লাইপই কেবল আলাদাভাবে নির্দিষ্ট করা যায়নি, এটি প্রাথমিকভাবে দেখা গেছে। রেভ -6 নথিটি স্পষ্টভাবে এই মজাদার বন্ধনী আচরণটি যুক্ত করেছে, তবে যুক্তিটি এড়িয়ে গেছে :( আমি এখন অনুমান করি যে উত্তরটি ঠিক
তেমনই কাছাকাছি ছিল

এবং তবুও কেউ দুটি স্বতন্ত্র ফাংশনগুলির জন্য দুটি স্বতন্ত্র কীওয়ার্ড তৈরি করে বোকা সমস্যার সমাধান করার প্রস্তাব দেয়নি? কমিটির অন্যতম বৃহত্তম ত্রুটি (এটি historতিহাসিকভাবে অনেকগুলি অবিস্মরণীয় ত্রুটি করেছে)।
কৌতূহলী

13

প্রথম বন্ধনী কেন অন্যরকম আচরণ করা হয়?

প্যারেন্টিহিসগুলি আলাদাভাবে ব্যবহার করা হয় না। এটি অপ্রতীকৃত আইডি-এক্সপ্রেশন যা আলাদাভাবে চিকিত্সা করা হয়।

প্রথম বন্ধনী উপস্থিত থাকলে সমস্ত অভিব্যক্তির নিয়মিত নিয়ম প্রযোজ্য। প্রকার এবং মান বিভাগটি প্রকারভেদে আহরণ এবং কোডেড হয় decltype

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

যদি আমরা একটি অভিব্যক্তি হিসাবে ভেরিয়েবলের বৈশিষ্ট্যগুলি সম্পর্কে যত্নশীল হয়ে থাকি তবে আমরা এটির পরিবর্তে আরও অতিরিক্ত বন্ধনী যুক্ত করতে পারি।


সুতরাং একটি জন্য intসদস্য iএর a, decltype(a.i)হয় intযখন decltype((a.i))হয় int&(অভিমানী aহয় না const)? যেহেতু অভিব্যক্তি a.iনিয়োগযোগ্য?
n314159

1
@ n314159 - এটি এর মূল বক্তব্য। এক্সপ্রেশনটি a.iএকটি নিরপেক্ষ লভ্যালু, সুতরাং আপনি এর জন্য একটি নন-কনস্ট্যান্ট লভ্যালু রেফারেন্স টাইপ পাবেন (a.i)
গল্পগ্রাহক - আনস্ল্যান্ডার মনিকা

কেন 'সমস্ত অভিব্যক্তির নিয়মিত নিয়ম' নির্দেশ করে যে তাদের ধরণটি একটি রেফারেন্স? কেন 'এক্সপ্রেশন হিসাবে ভেরিয়েবলের বৈশিষ্ট্য' রেফারেন্স হওয়ার সম্পত্তি যুক্ত করে? এটি কিছু প্রাকৃতিক ডিফল্ট?
ওফেক শিলন

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

@ স্টেটরি টেলার ঠিক বলেছেন, ধরণের অভিব্যক্তি এবং অ অভিব্যক্তির মধ্যে কোনও 'প্রাকৃতিক' পার্থক্য নেই। যা পার্থক্যকে কৃত্রিম করে তোলে।
ওফেক শিলন

1

প্রাক সি ++ 11 পূর্বের দুটি ভিন্ন ধরণের তথ্য পেতে ভাষার সরঞ্জাম (গুলি) দরকার :

  • একটি অভিব্যক্তি টাইপ
  • এটি যেমন ঘোষিত হয়েছিল তেমনি একটি ভেরিয়েবলের ধরণ

এই তথ্যের প্রকৃতির কারণে, বৈশিষ্ট্যগুলি ভাষায় যুক্ত করতে হয়েছিল (এটি কোনও লাইব্রেরিতে করা যায় না)। এর অর্থ নতুন কীওয়ার্ড (গুলি)। স্ট্যান্ডার্ডটি এর জন্য দুটি নতুন কীওয়ার্ড চালু করতে পারে। উদাহরণস্বরূপ exprtypeএকটি এক্সপ্রেশনের decltypeধরণ পেতে এবং একটি ভেরিয়েবলের ঘোষণার ধরণ পেতে। এটি পরিষ্কার, খুশির বিকল্প হত।

তবে পুরানো কোডের ভাঙ্গন কমানোর জন্য স্ট্যান্ডার্ড কমিটি ভাষাটিতে নতুন কীওয়ার্ডগুলি এড়াতে এড়াতে সর্বদা সর্বাত্মক চেষ্টা করেছে । পিছনের সামঞ্জস্যতা ভাষার মূল দর্শন।

তাই সি ++ 11 আমরা মাত্র এক শব্দ দুটি ভিন্ন জিনিস জন্য ব্যবহৃত করেছেন: decltype। এটি দুটি ব্যবহারের মধ্যে যেভাবে পার্থক্য করে তা হ'ল decltype(id-expression)আলাদাভাবে চিকিত্সা করা । এটি কমিটির একটি সচেতন সিদ্ধান্ত ছিল, একটি (ছোট) আপস।


আমার মনে আছে এটি সিপিসি টকটিতে শুনেছি। আমার অবশ্য উত্স খুঁজে পাওয়ার কোন আশা নেই। কেউ এটি পেলে দুর্দান্ত হবে।
বলভ

1
সি ++ historতিহাসিকভাবে একাধিক নতুন কীওয়ার্ড যুক্ত করেছে, অনেকগুলি ডাব্লু / ও আন্ডারস্কোর এবং কিছুতে একটি ইংরেজি শব্দ রয়েছে। যৌক্তিক সত্যই অযৌক্তিক।
কৌতূহলী

@ কুরিয়াসগুয়ে প্রবর্তিত প্রতিটি কীওয়ার্ড বিদ্যমান ব্যবহারকারীর প্রতীকগুলির সাথে সংঘর্ষ করবে তাই কমিটি ভাষায় নতুন সংরক্ষিত কীওয়ার্ড যুক্ত করার সিদ্ধান্তকে ভারী ওজন দেয়। এটি অযৌক্তিক ইমো নয়।
বলভ

সত্য নয়: exportপরিচয় হয়েছিল। যদি আপনি থাকতে পারেন export(পূর্বে সমস্ত টেম্পলেটগুলি ডিফল্টরূপে "রফতানি" হত), আপনার মতো জিনিস থাকতে পারে decltypeএবং constexpr। স্পষ্টতই registerঅন্য ভাষায় যুক্ত করা সমস্যাযুক্ত হবে।
কৌতূহলী

@ বলভো ধন্যবাদ! (1) এই জল্পনা বা জ্ঞান? একটি অতিরিক্ত কীওয়ার্ড এড়ানো অনুপ্রেরণা ছিল এমন আলোচনার বিষয়ে আপনি কি সচেতন? (২) আপনি একটি উদাহরণ দিতে পারেন যেখানে কোনও আইডি-এক্সপ্রেশনকে "অভিব্যক্তি হিসাবে" ব্যবহার করা হলে আসলে আলাদা আচরণ করা দরকার? (এটি এমনকি এর অর্থ কী?)
ওফেক শিলন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.