ত্রুটি: 'int' টাইপের একটি মূল্য থেকে 'int &' টাইপের নন-কনস্ট্যান্ট রেফারেন্সের অবৈধ সূচনা


87

ভুল ফর্ম:

int &z = 12;

সঠিক গঠন:

int y;
int &r = y;

প্রশ্ন :
প্রথম কোডটি ভুল কেন? শিরোনামে ত্রুটির" অর্থ "কী?


4
অস্থায়ী অ-ধ্রুবক রেফারেন্সে আবদ্ধ হতে পারে না। এই ক্ষেত্রে int (12) একটি অস্থায়ী।
প্রসূন সৌরভ

@ প্রসূনসৌরভ অস্থায়ী 12 এর অর্থ কী? এখানে ধারণাগুলির অভাব (আমার পক্ষ থেকে :))
কুম্ভ_র_গর্ভা

4
মনে রাখবেন যে এই সীমাবদ্ধতার জন্য কোনও কঠোর প্রযুক্তিগত কারণ নেই। অস্থায়ীগুলিতে পরিবর্তনীয় রেফারেন্সগুলিকে অনুমতি দেওয়ার জন্য এটি প্রয়োগ করা ঠিক তত সহজ ছিল easy নিষিদ্ধ করা এটি সি ++ এর একটি ডিজাইনের সিদ্ধান্ত , যেহেতু এই ধরনের নির্মাণ হ'ল প্রকৃত ইউটিলিটির চেয়ে অজান্তে অপব্যবহারের ঝুঁকি সহ নিম্নতর নকশা হবে। (আমি কেবল একবারই এই জাতীয় জিনিসের জন্য একটি অনুমোদিত প্রয়োজন খুঁজে পেয়েছি))
কেরেরেক এসবি

@ কেরেকএসবি হ'ল বাধ্যবাধকতার সাথে মূল্যায়ন করার জন্য সবচেয়ে সাধারণ প্রয়োজন সম্ভবত(ostringstream() << "x=" << x).str()
কৌতূহলী

@ কুরিয়াসগুয়ে: হ্যাঁ, আমি পোস্ট করা লিঙ্কটির বিষয়বস্তু এটি।
কেরেক এসবি

উত্তর:


133

সি ++ 03 3.10 / 1 বলেছেন: "প্রতিটি অভিব্যক্তি হয় একটি মূল্য বা মূল্য val" এটা মনে রাখা গুরুত্বপূর্ণ যে স্বচ্ছতা বনাম মূল্যবৃদ্ধি হ'ল অভিব্যক্তির সম্পত্তি, বস্তুর নয়।

ল্যাভেলুয়েসগুলির নামের নাম অবজেক্টস যা একক অভিব্যক্তির বাইরেও অবিচল থাকে। উদাহরণস্বরূপ, obj, *ptr, ptr[index], এবং ++xসব lvalues হয়।

মূল্যগুলি হ'ল অস্থায়ী যা সম্পূর্ণ-এক্সপ্রেশন যেখানে তারা বাস করে ("সেমিকোলনে") শেষে বাষ্পীভূত হয়। উদাহরণস্বরূপ, 1729, x + y, std::string("meow"), এবং x++সব rvalues হয়।

অপারেটরের ঠিকানাটির প্রয়োজন হয় এটির "অপারেন্ডটি একটি মূল্য হবে"। আমরা যদি একটি অভিব্যক্তির ঠিকানা নিতে পারি, ভাবটি হ'ল মূল্য, অন্যথায় এটি একটি মূল্য।

 &obj; //  valid
 &12;  //invalid

4
" যদি আমরা একটি এক্সপ্রেশনের ঠিকানা নিতে পারি, তবে এক্সপ্রেশনটি একটি লভ্যালু হয়, নাহলে এটি একটি মূল্যমান " "যদি কেবল সি ++ এমন সরল ছিল! (তবে উপহাসটি এখানে প্রকৃত পক্ষে প্রাসঙ্গিক নয়) "মূল্যবোধগুলি অস্থায়ী হয়" অস্থায়ী কী? বস্তু?
কৌতূহলী

4
@ কুরিয়াসগুয়ের মূল্যগুলি হ'ল অস্থায়ী যা সম্পূর্ণরূপে যেখানে তারা বাস করে তার শেষে অদৃশ্য হয়ে যায়। এক্সপ্রেসটি কেন int & = 12;অবৈধ তা কেবল উত্তর দেওয়ার জন্য, স্ট্যান্ডার্ডটি বলে যে স্ট্রিং আক্ষরিক একটি লভ্যালু, অন্যান্য আক্ষরিক মূল্যগুলি val
ব্রুসএডি

@ কুরিয়াসগুয়ে: হ্যাঁ মূল্যবোধগুলি অস্থায়ী বস্তু , তবে সমস্ত মূল্যবোধ অস্থায়ী বস্তু নয়; কিছু এমনকি বস্তু হয় না।
নওয়াজ

" উদাহরণস্বরূপ, 1729, এক্স + Y জন্য, std :: স্ট্রিং (" মীআও "), এবং এক্স ++, সব rvalues হয়। " কিন্তু std::string("meow")প্রকারের একটি বস্তু নির্মান std::stringএবং rvalue যে এই বস্তু designates, উৎপাদ 1729কোন পার্শ্ব প্রতিক্রিয়া এবং উৎপাদনের মান আছে 1729 টাইপের একটি মূল্য হিসাবে int
কৌতূহলী

4
@ কুরিয়াসগুই: বিবৃতিটি "Lvalues name objects that persist beyond a single expression."একটি 100% সঠিক বিবৃতি। বিপরীতে, আপনার উদাহরণটি (const int &)1ভুল, কারণ এটি কোনও "নামযুক্ত" বস্তু নয়।
নওয়াজ

53
int &z = 12;

ডানদিকে, intঅবিচ্ছেদ্য আক্ষরিক থেকে টাইপের একটি অস্থায়ী বস্তু তৈরি করা হয় 12, তবে অস্থায়ীটি অ-কনস্ট্যান্ট রেফারেন্সে আবদ্ধ হতে পারে না। সুতরাং ত্রুটি। এটি যেমন:

int &z = int(12); //still same error

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

একটি অস্থায়ী বস্তু রেফারেন্সের সাথে আবদ্ধ হতে পারে, যার অর্থ আপনি এটি করতে পারেন:

const int &z = 12; //ok

সি ++ 11 এবং মূল্যায়ন রেফারেন্স:

সম্পূর্ণতার জন্য, আমি যুক্ত করতে চাই যে সি ++ 11 রুল্যু-রেফারেন্স চালু করেছে, যা অস্থায়ী বস্তুর সাথে আবদ্ধ হতে পারে। সুতরাং সি ++ 11 এ আপনি এটি লিখতে পারেন:

int && z = 12; //C+11 only 

লক্ষ করুন যে এর &&আন্তঃ আছে &। এছাড়াও নোট করুন যে constআর প্রয়োজন হয় না, যদিও যে বস্তুটি zবেঁধে রাখে তা অবিচ্ছেদ্য-আক্ষরিক থেকে তৈরি অস্থায়ী বস্তু 12

যেহেতু সি ++ 11 মূল মূল্য-রেফারেন্স চালু করেছে , int&এখন থেকে তাকে বলা হয় ল্যাভেলু-রেফারেন্স


10

12একটি সংকলন-সময় ধ্রুবক যা রেফারেন্সকৃত ডেটার বিপরীতে পরিবর্তন করা যায় না int&। আপনি যা করতে পারেন তা হ'ল

const int& z = 12;

4
@ কুরিয়াসগুয়ে, ধারাবাহিক থাকুন, আপনি বলেছিলেন "আপনাকে বুঝতে হবে যে এগুলি সি ++ নিয়ম They এগুলি বিদ্যমান রয়েছে এবং তাদের কোন ন্যায়সঙ্গততার প্রয়োজন নেই" (প্রথম সংস্করণের উল্লেখ না করার জন্য)। আপনার নিজের অনুসারে যা প্রয়োজন হয় না তা দেওয়ার অভিযোগ করার আমি কীভাবে ব্যাখ্যা করব?
মাইকেল ক্রেলিন - হ্যাকার

4
@ মাইকেল ক্রেলিন-হ্যাকার: প্রযুক্তিগতভাবে নয়, আপনি কোনও মান (বা সময় ধ্রুবককে সংকলন) করার জন্য (কখনই) বাঁধতে পারবেন না, স্ট্যান্ডার্ডটি আসলে কী ঘটে তা সম্পর্কে পুরোপুরি স্পষ্ট: অন্যথায়, "সিভি 1 টি 1" টাইপের একটি অস্থায়ী তৈরি হয় এবং অ-রেফারেন্স অনুলিপি-ইনিশিয়ালাইজেশন (8.5) এর নিয়ম ব্যবহার করে ইনিশিয়ালাইজার এক্সপ্রেশন থেকে আরম্ভ করা। এরপরে রেফারেন্সটি অস্থায়ী হিসাবে আবদ্ধ হয়, সিনট্যাক্স অনুমোদিত, তবে শব্দার্থকরা ধ্রুবককে একটি রেফারেন্স বাঁধাই করে না, বরং এটি অস্থায়ীভাবে আবদ্ধ করে যা অস্থায়ীভাবে তৈরি হয় b
ডেভিড রদ্রিগেজ - ড্রিবিস

4
@ কুরিয়াসগুয়ে: ভাষার বিধিগুলি ডিজাইনের একটি অংশ এবং প্রায়শই এটির চেয়েও বেশি, ভাষাটি কেন এরকমভাবে ডিজাইন করা হয়েছিল সে সম্পর্কে ন্যায্যতা রয়েছে। এই নির্দিষ্ট ক্ষেত্রে, সি হিসাবে আপনাকে কোনও মানের ঠিকানা নেওয়ার অনুমতি নেই (এটির একটি নেই), আপনি কোনও রেফারেন্সও বেঁধে রাখতে পারবেন না। এখন একটি ফাংশন বিবেচনা করুন void f( vector<int> const & ), যা কোনও ভেক্টরকে সংশোধন করতে হবে না তা পাস করার জন্য মূর্তিমান। এখন সমস্যাটি হ'ল এটি f( vector<int>(5) )ভুল হবে এবং ব্যবহারকারীকে একটি আলাদা ওভারলোড সরবরাহ করতে হবে void f( vector<int> v ) { f(v); }যা তুচ্ছ।
ডেভিড রদ্রিগেজ - ড্রিবিস

4
... এখন যেহেতু ভাষার ব্যবহারকারীদের জন্য এটি বেদনাদায়ক হবে, তাই ডিজাইনাররা সিদ্ধান্ত নিয়েছিলেন যে সংকলকটি আপনার জন্য সমান ক্রিয়াকলাপ করবে, কলটিতে f( vector<int>(5) )সংকলক একটি অস্থায়ী তৈরি করে এবং তারপরে সেই অস্থায়ীটির রেফারেন্সকে বেঁধে রাখে এবং একইভাবে যদি 5সরাসরি থেকে কোনও অন্তর্নিহিত রূপান্তর হয় । এটি সংকলকটি ফাংশনের জন্য একটি একক স্বাক্ষর তৈরি করতে দেয় এবং ফাংশনের একক ব্যবহারকারীর প্রয়োগ সক্ষম করে। সেখান থেকে, ধারাবাহিকতার জন্য ধ্রুবক রেফারেন্সগুলির অবশিষ্ট ব্যবহারের জন্য অনুরূপ আচরণটি সংজ্ঞায়িত করা হয়।
ডেভিড রদ্রিগেজ - শুক্র

4
@ MichaelKrelin-হ্যাকার: রেফারেন্স alias লেখা বস্তু, এবং একটি মান একটি অবজেক্ট নয়। প্রসঙ্গের উপর নির্ভর করে, রেফারেন্সগুলি কেবলমাত্র উরফ হতে পারে সংকলকটি রেফারেন্সটি সরিয়ে দেয় এবং মূল সনাক্তকারীটিকে যা বোঝায় তা বোঝাতে কেবল সনাক্তকারী ব্যবহার করে ( T const & r = *ptr;, rফাংশনে কোনও পরবর্তী ব্যবহার প্রতিস্থাপন করা যেতে পারে *ptr, এবং rরানটাইমটিতে বিদ্যমান থাকার প্রয়োজন নেই) অথবা এটি কোনও পদক্ষেপের (যেমন কোনও বস্তুর সদস্য হিসাবে একটি রেফারেন্স সংরক্ষণ করার বিবেচনা করুন) ঠিকানা রেখে এই প্রয়োগ করতে হতে পারে - যা একটি স্বতঃসংশ্লিষ্ট পয়েন্টার হিসাবে প্রয়োগ করা হয়।
ডেভিড রদ্রিগেজ - ড্রিবিস

4

নন-কনস্ট এবং কনস্টের রেফারেন্স বাইন্ডিং বিভিন্ন নিয়ম অনুসরণ করে

এগুলি সি ++ ভাষার নিয়ম:

  • আক্ষরিক সংখ্যার সমন্বয়ে প্রকাশ ( 12) একটি "মূল্য"
  • এটি একটি rvalue সঙ্গে একটি অ-const রেফারেন্স তৈরি করতে অনুমোদিত নয়: int &ri = 12;মন্দ গঠিত
  • এটি কোনও মূল্যের সাথে একটি কনস্টের রেফারেন্স তৈরি করার অনুমতিপ্রাপ্ত: এক্ষেত্রে সংকলক দ্বারা একটি নামহীন অবজেক্ট তৈরি করা হয়েছে; রেফারেন্স নিজেই উপস্থিত থাকা অবধি এই অবজেক্টটি স্থির থাকবে।

আপনাকে বুঝতে হবে যে এটি সি ++ নিয়ম। তারা ঠিক আছে।

কিছুটা আলাদা বিধি সহ আলাদা আলাদা ভাষা উদ্ভাবন করা সহজ, সি ++ 'বলুন। সি ++ 'তে, এটি কোনও মূল্যমানের সাথে একটি নিরপেক্ষ রেফারেন্স তৈরি করার অনুমতি দেওয়া হবে। এখানে অসঙ্গত বা অসম্ভব কিছু নেই।

তবে এটি এমন কিছু ঝুঁকিপূর্ণ কোডের মঞ্জুরি দেবে যেখানে প্রোগ্রামার তার উদ্দেশ্যটি নাও পেতে পারে এবং সি ++ ডিজাইনাররা ঠিক সেই ঝুঁকি এড়াতে সিদ্ধান্ত নিয়েছে।


0

উল্লেখগুলি হ'ল "লুকানো পয়েন্টার" (অ-নাল) এমন জিনিসের প্রতি পরিবর্তন করতে পারে (মানগুলি)। আপনি একটি ধ্রুবক তাদের সংজ্ঞায়িত করতে পারবেন না। এটি একটি "পরিবর্তনশীল" জিনিস হওয়া উচিত।

সম্পাদনা ::

আমি ভাবছি

int &x = y;

প্রায় সমতুল্য হিসাবে

int* __px = &y;
#define x (*__px)

__pxএকটি নতুন নাম কোথায় , এবং #define xকেবলমাত্র xরেফারেন্সের ঘোষণামূলক ব্লকের ভিতরে কাজ করে ।


4
আপনি কেন পারেন, যদি রেফারেন্স হয় const:)
মাইকেল ক্রেলিন - হ্যাকার

তবে পোস্টারের উদাহরণটি ছিল নাconst
বেসাইল স্টারিনকিভিচ

হ্যাঁ, আমি আপনার শব্দটি বোঝাতে চাইছি "রেফারেন্সগুলি এমন জিনিসগুলির দিকে নির্দেশ করে যা পরিবর্তন করতে পারে" - এটি ব্যয়বহুল রেফারেন্স সম্পর্কে।
মাইকেল ক্রেলিন - হ্যাকার

" রেফারেন্সগুলি হ'ল " লুকানো পয়েন্টার " " ভুল " যা " ভুল " জিনিসগুলিকে বদলে দিতে পারে (মানগুলি) " "ভুল
কৌতূহলী

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