সি ++ এর লুকানো বৈশিষ্ট্য? [বন্ধ]


114

প্রশ্নাবলীর "লুকানো বৈশিষ্ট্যগুলি" কী আসে যায় না? ভেবেছিলাম আমি ওখানে ফেলে দেব। সি ++ এর কিছু লুকানো বৈশিষ্ট্য কী কী?


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

5
@ লইথ জে: খুব বেশি লোক 7866 পৃষ্ঠার আইএসও সি ++ স্ট্যান্ডার্ডটি কভার থেকে শুরু করে পড়েনি - তবে আমি মনে করি আপনার কাছে আছে, এবং আপনি এটি সব ধরে রেখেছেন, তাই না?
j_random_hacker

2
@Laith, @j_random: আমার প্রশ্ন "কি প্রোগ্রামার এর রসিকতা, আমি এটা কিভাবে চিনতে পারি, এবং কি যথাযথ প্রতিক্রিয়া হয়" এ আপনি দেখুন stackoverflow.com/questions/1/you-have-been-link-rolled

দেখুন meta.stackexchange.com/questions/56669/... , meta.stackexchange.com/questions/57226/... এবং সম্পর্কিত মেটা পোস্ট নেই।

উত্তর:


308

বেশিরভাগ সি ++ প্রোগ্রামারগুলি টের্নারি অপারেটরের সাথে পরিচিত:

x = (y < 0) ? 10 : 20;

তবে, তারা বুঝতে পারে না যে এটি একটি মূল্য হিসাবে ব্যবহার করা যেতে পারে:

(a == 0 ? a : b) = 1;

যা সংক্ষিপ্ত

if (a == 0)
    a = 1;
else
    b = 1;

সতর্কতার সাথে ব্যবহার করুন :-)


11
খুব আকর্ষণীয়. আমি দেখতে পাচ্ছি যে যদিও কিছু অপঠনযোগ্য কোড তৈরি করা হচ্ছে।
জেসন বেকার

112
বাবা। (a == 0? a: b) = (y <0? 10: 20);
জ্যাস্পার বেকারস

52
(খ? সত্যিকারের হিসাব: মিথ্যা হিসাব) ++
পাভেল

12
জানিনা যদি এটা জিসিসি নির্দিষ্ট, কিন্তু আমি এটাও কাজ খুঁজে বিস্মিত হয়েছিল: (value ? function1 : function2)()
ক্রিস বার্ট-ব্রাউন

3
@ ক্রিস বার্ট-ব্রাউন: না, যদি তাদের একই ধরণের (অর্থাত্ কোনও খেলাপী যুক্তি না থাকে) সর্বত্র কাজ করা উচিত function1এবং function2জড়িতভাবে ফাংশন পয়েন্টারে রূপান্তরিত হয় এবং ফলাফলটি স্পষ্টতই ফিরে রূপান্তরিত হয়।
এমসাল্টার

238

আপনি ত্রুটি ছাড়াই সি ++ উত্সে ইউআরআই রাখতে পারেন। উদাহরণ স্বরূপ:

void foo() {
    http://stackoverflow.com/
    int bar = 4;

    ...
}

41
তবে ফাংশন প্রতি মাত্র একজন, আমার সন্দেহ? :)
কনস্টান্টিন

51
@ জেপোহ: কোলন অনুসারে HTTP একটি "লেবেল" হয়ে যায় যা আপনি পরে গোটো স্টেটমেন্টে ব্যবহার করেন। আপনি আপনার সংকলক থেকে সেই সতর্কতা পেয়েছেন কারণ এটি উপরের উদাহরণে কোনও গোটো বিবৃতিতে ব্যবহৃত হয়নি।
উত্কু_করটাস

9
যতক্ষণ না তাদের প্রোটোকল রয়েছে ততক্ষণ আপনি একাধিক সংখ্যক যুক্ত করতে পারেন! এফটিপি.মাইক্রোসফট.কম গফার: //aerv.nl/1 এবং আরও ...
ড্যানিয়েল আরউইকার

4
@ পাভেল: কোলন অনুসরণকারী একটি সনাক্তকারী হ'ল একটি লেবেল (সাথে ব্যবহারের জন্য goto, যা সি ++ থাকে)। দুটি টুকরো টুকরো করে নিম্নলিখিত যে কোনও কিছু মন্তব্য thing অতএব, এর সাথে http://stackoverflow.com, httpএকটি লেবেল (আপনি তাত্ত্বিকভাবে লিখতে পারেন goto http;), এবং //stackoverflow.comএটি কেবল একটি শেষ-লাইন মন্তব্য। এগুলি উভয়ই আইনী সি ++, তাই সংকলনগুলি তৈরি করুন। এটি অবশ্যই অস্পষ্টভাবে কার্যকর কিছু করে না।
ডেভিড থর্নলি

8
দুর্ভাগ্যক্রমে goto http;আসলে URL টি অনুসরণ করে না। :(
ইয়াকভ গালকা

140

পয়েন্টার গাণিতিক।

সি ++ প্রোগ্রামাররা যে বাগগুলি প্রবর্তন করা যেতে পারে তার কারণে পয়েন্টার এড়াতে পছন্দ করে।

দুর্দান্ত সি ++ আমি কি কখনও দেখেছি? অ্যানালগ আক্ষরিক।


11
আমরা বাগের কারণে পয়েন্টার এড়াতে চাই? পয়েন্টারগুলি হ'ল গতিশীল সি ++ কোডিং সম্পর্কে যা কিছু আছে!
নিক বেডফোর্ড

1
অ্যানালগ লিটারালগুলি অস্পষ্ট সি ++ প্রতিযোগিতার এন্ট্রিগুলির জন্য বিশেষত ASCII- আর্ট টাইপের জন্য দুর্দান্ত।
Synetech

119

আমি সেখানে বেশিরভাগ পোস্টের সাথে একমত: সি ++ একটি বহু-দৃষ্টিকোণ ভাষা, সুতরাং যে "গোপন" বৈশিষ্ট্যগুলি আপনি পাবেন ("অপরিজ্ঞাত আচরণগুলি" ব্যতীত যা আপনার কোনও মূল্যে এড়ানো উচিত) হ'ল সুবিধার সুবিধাযুক্ত ব্যবহার।

এই সুবিধাগুলিগুলির বেশিরভাগ ভাষাটির বিল্ট-ইন বৈশিষ্ট্যগুলি নয়, তবে গ্রন্থাগার-ভিত্তিক।

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

ব্যতিক্রমের ব্যবহার প্রায়শই কঠিন, তবে কিছু কাজ করে, ব্যতিক্রমী সুরক্ষা বৈশিষ্ট্যের মাধ্যমে সত্যিকারের শক্ত কোড তৈরি করতে পারে (কোড সহ যা ব্যর্থ হবে না, বা এতে কমিটের মতো বৈশিষ্ট্য রয়েছে যা সফল হবে, বা ফিরে ফিরে যাবে) এর মূল অবস্থা)।

সি ++ এর সর্বাধিক বিখ্যাত "লুকানো" বৈশিষ্ট্যটি হ'ল টেমপ্লেট বিপণন , কারণ এটি আপনাকে রানটাইমের পরিবর্তে সংকলন সময়ে আপনার প্রোগ্রামটি আংশিক (বা সম্পূর্ণ) সম্পাদন করতে সক্ষম করে। এটি যদিও এটি কঠিন, এবং এটির চেষ্টা করার আগে আপনার অবশ্যই টেমপ্লেটগুলিতে একটি দৃ gra় দখল থাকা উচিত।

অন্যান্য সি ++ এর পূর্বপুরুষের বাইরে, অর্থাৎ সি এর বাইরে "প্রোগ্রামিংয়ের পদ্ধতি" তৈরি করতে একাধিক দৃষ্টান্ত ব্যবহার করে make

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

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

আমি খুঁজে পেয়েছি যে স্কট মায়ার্সের বেশিরভাগ " কার্যকর সি ++ " - টাইপ বইগুলি বা " ব্যতিক্রমী সি ++ " - হার্ব সটারের টাইপ বইগুলি উভয়ই পড়া সহজ, এবং সি ++ এর জ্ঞাত এবং কম পরিচিত বৈশিষ্ট্যগুলির তথ্যের বেশিরভাগ ধনকোষ।

আমার পছন্দের মধ্যে একটি হ'ল যে কোনও জাভা প্রোগ্রামারের চুলকে ভয়ঙ্কর থেকে উত্থিত করা উচিত: সি ++ এ, কোনও অবজেক্টে কোনও বৈশিষ্ট্য যুক্ত করার সর্বাধিক অবজেক্ট-ওরিয়েন্টেড উপায় হ'ল সদস্যের পরিবর্তে অ-সদস্যবিহীন বন্ধু-বান্ধব ক্রিয়াকলাপের মাধ্যমে- ফাংশন (অর্থাত ক্লাস পদ্ধতি), কারণ:

  • সি ++ তে, একটি শ্রেণি ইন্টারফেস তার সদস্য-কার্য এবং একই নেমস্পেসে অ-সদস্য ফাংশন উভয়ই

  • অ-বন্ধুহীন অ-সদস্যের কার্যক্রমে অভ্যন্তরীণ শ্রেণিতে কোনও সুযোগ সুবিধা নেই to এর মতো, অ-সদস্যের অ-বন্ধুর উপরে সদস্য ফাংশন ব্যবহার করা ক্লাসের 'এনপ্যাপসুলেশনকে দুর্বল করে দেয়।

এটি অভিজ্ঞ বিকাশকারীদেরও অবাক করে না।

(উত্স: অন্যদের মধ্যে, ভেষজ সুটারের সপ্তাহের অনলাইন গুরু # 84: http://www.gotw.ca/gotw/084.htm )


+1 খুব ভাল উত্তর। এটি সুস্পষ্ট কারণে অসম্পূর্ণ (অন্যথায় "লুকানো বৈশিষ্ট্যগুলি আর থাকবে না!): p উত্তরটির প্রথম পয়েন্টে, আপনি একটি শ্রেণি ইন্টারফেসের সদস্যদের উল্লেখ করেছেন। আপনার অর্থ ".. এর সদস্য-কার্যাবলী এবং বন্ধু উভয়ই কি সদস্যবিহীন ফাংশন"?
wilhelmtell


আপনি 1 এর সাথে যা উল্লেখ করছেন তা অবশ্যই কোনিগ লুকআপ হতে হবে, তাই না?
üzgür

1
@ উইলহেলমটেল: না নো ... :- পি ... আমি এর অর্থ "এর সদস্য-কার্যাবলী এবং নন-ফ্রেন্ড অ-সদস্যের ক্রিয়াকলাপ" .... কোয়েনিগের অনুসন্ধান নিশ্চিত করবে যে এই ফাংশনগুলিকে অন্যান্যগুলির তুলনায় শীঘ্রই বিবেচনা করা হবে " বাইরের "প্রতীকগুলির সন্ধানে ফাংশনগুলি
প্যাসেসারবাল

7
দুর্দান্ত পোস্ট এবং বিশেষত শেষ অংশের জন্য +1, যা খুব কম লোকই বুঝতে পারে। আমি সম্ভবত বুস্ট লাইব্রেরিকে একটি "লুকানো বৈশিষ্ট্য" হিসাবে যুক্ত করতাম। আমি বেশিরভাগই এটি স্ট্যান্ডার্ড লাইব্রেরি বিবেচনা করি যা সি ++ থাকা উচিত ছিল। ;)
জাল্ফ

118

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

namespace fs = boost::filesystem;

fs::path myPath( strPath, fs::native );

1
আমার ধারণা আপনি যদি ব্যবহার করতে না চান তবে এটি কার্যকর using
সিকি লিন

4
থ্রেড-সেফ বনাম থ্রেড-সেফ বনাম নন-থ্রেড-সেফ বা সংস্করণ 1 বনাম 2 নির্বাচন করা কিনা তা বাস্তবায়নের মধ্যে পরিবর্তন করার উপায় হিসাবেও এটি কার্যকর
টনি দেলরোয়

3
এটি বিশেষত কার্যকর যদি আপনি বৃহত নেমস্পেস হায়ারারচিগুলির সাথে একটি খুব বড় প্রকল্পে কাজ করছেন এবং আপনি চান না যে আপনার শিরোনামগুলি নাম স্থানটি দূষণ করে (এবং আপনি চান যে আপনার পরিবর্তনশীল ঘোষণাগুলি মানব-পঠনযোগ্য হোক) able
ব্র্যান্ডন বোহার

102

একটি forলুপের init অংশে কেবল ভেরিয়েবলগুলিই ঘোষিত হতে পারে না , তবে শ্রেণি এবং ক্রিয়াকলাপগুলিও।

for(struct { int a; float b; } loop = { 1, 2 }; ...; ...) {
    ...
}

এটি বিভিন্ন ধরণের একাধিক ভেরিয়েবলের অনুমতি দেয়।


31
আপনি এটি করতে পারেন তা জেনে ভাল লাগছে তবে ব্যক্তিগতভাবে আমি এমন কিছু করা এড়াতে চেষ্টা করব। বেশিরভাগ কারণ এটি পড়া কঠিন।
জুমুলেটর 21

2
প্রকৃতপক্ষে, এই প্রসঙ্গে কী কাজ করবে তা একটি জোড় ব্যবহার করছে: (স্টাড :: জোড় <ইন, ফ্লোট> লুপ = স্টেডি :: মেক_ পেয়ার (1,2); লুপ.ফার্স্ট> 0; লুপ.সেকেন্ড + = 1)
ভ্যালেন্টিন হেইনিটজ

2
@ ভ্যালেনটিন ভাল তবে আমি আপনাকে পরামর্শ দিচ্ছি যে লুকানো বৈশিষ্ট্যটি বাদ দিয়ে পরিবর্তে VS2008 এর বিরুদ্ধে একটি বাগ্রেপোর্ট তৈরি করার চেষ্টা করুন। এটি পরিষ্কারভাবে আপনার সংকলকের দোষ।
জোহানেস স্কাউব - 21

2
হুম, এটি এমএসভিসি 10 তেও কাজ করে না। কত দুঃখজনক :(
অবাক

2
@ প্রকৃতপক্ষে, জিসিসি একটি বাগ প্রবর্তন করেছে যা এটি খুব তাড়াতাড়ি বাতিল করে দেয়, ভি ৪..6
জোহানেস স্কাউব - লিটব

77

অ্যারে অপারেটরটি সহযোগী।

এ [8] হ'ল * (এ + 8) এর প্রতিশব্দ। যেহেতু সংযোজনমূলক, তাই এটি * (8 + এ) হিসাবে আবারও লেখা যেতে পারে, যা ..... 8 [এ] এর প্রতিশব্দ

আপনি দরকারী বলেছেন না ... :-)


15
আসলে, এই কৌশলটি ব্যবহার করার সময়, আপনি কী ধরণের ব্যবহার করছেন সেদিকে আপনার সত্যই মনোযোগ দেওয়া উচিত। এ [8] হ'ল 8 তম এ এবং 8 [এ] অ্যাথ পূর্ণসংখ্যা 8 ঠিকানায় শুরু হয় A
ভিনসেন্ট রবার্ট 0

38
আপনি যেখানে "সাহসী" বলছেন তার অর্থ "পরিবর্তনশীল"?
DarenW

28
ভিনসেন্ট, আপনি ভুল ধরণ Aএ সব কোন ব্যাপার না। উদাহরণস্বরূপ, যদি Aএটি হয় char*তবে কোডটি এখনও বৈধ হবে।
কনরাড রুডল্ফ

11
সাবধান হন যে এ অবশ্যই পয়েন্টার হতে হবে, এবং ক্লাস ওভারলোডিং অপারেটর নয় []।
ডেভিড রদ্রিগেজ - ড্রিবাস

15
ভিনসেন্ট, এর মধ্যে একটি ইন্টিগ্রাল টাইপ এবং একটি পয়েন্টার টাইপ থাকতে হবে, এবং সি বা সি ++ উভয়ই প্রথমে কোনটির যত্ন করে না।
ডেভিড থর্নলি

73

একটি জিনিস যা খুব কম জানা যায় তা হ'ল ইউনিয়নগুলিও টেম্পলেট হতে পারে:

template<typename From, typename To>
union union_cast {
    From from;
    To   to;

    union_cast(From from)
        :from(from) { }

    To getTo() const { return to; }
};

এবং তারা কনস্ট্রাক্টর এবং সদস্য ফাংশনও থাকতে পারে। উত্তরাধিকারের সাথে কেবল কিছুই করার নেই (ভার্চুয়াল ফাংশন সহ)।


মজাদার! সুতরাং, আপনার কি সমস্ত সদস্যকে আরম্ভ করা উচিত? এটি কি সাধারণ কাঠামোর আদেশ অনুসরণ করে বোঝায় যে শেষ সদস্যটি আগের সদস্যদের "শীর্ষে" শুরু করা হবে?
j_random_hacker

j_random_hacker ওহ, ঠিক এটাই বাজে কথা। ভালো বল ধরা. আমি এটি লিখেছি কারণ এটি একটি কাঠামো হবে। অপেক্ষা করুন আমি এটি ঠিক করব
জোহানেস স্কাউব -

এটি কি অনির্ধারিত আচরণের ডাক দেয় না?
গ্রেগ বেকন

7
@gbacon, হ্যাঁ যদি অনির্ধারিত আচরণ ডাকা করে Fromএবং Toসেট এবং ব্যবহার করা হয় সেই অনুযায়ী। এই জাতীয় ইউনিয়ন সংজ্ঞায়িত আচরণের সাথে ব্যবহার করা যেতে পারে যদিও ( Toস্বাক্ষরযুক্ত চরের অ্যারে হওয়া বা কোনও কাঠামোর সাথে প্রাথমিক ক্রম ভাগ করে নেওয়া From)। এমনকি আপনি এটি অপরিজ্ঞাত উপায়ে ব্যবহার করলেও এটি নিম্ন-স্তরের কাজের জন্য কার্যকর হতে পারে। যাইহোক, এটি ইউনিয়নের টেমপ্লেটের কেবল একটি উদাহরণ - একটি টেম্প্লেটেড ইউনিয়নের জন্য অন্যান্য ব্যবহার থাকতে পারে।
জোহানেস স্কাউব - 30:38

3
কনস্ট্রাক্টরের সাথে যত্নশীল। মনে রাখবেন যে আপনাকে কেবল প্রথম উপাদানটি তৈরি করতে হবে এবং এটি কেবলমাত্র C ++ 0x এ অনুমোদিত। বর্তমান মান হিসাবে, আপনি তুচ্ছ কাঠামোগত ধরণের আটকে থাকতে হবে। এবং কোনও ধ্বংসকারী নেই।
পোটোসওয়টার

72

সি ++ একটি মান, এখানে কোনও লুকানো বৈশিষ্ট্য থাকা উচিত নয় ...

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


65

আর একটি লুকানো বৈশিষ্ট্য যা সি তে কাজ করে না তা হ'ল ইউনিারি +অপারেটরের কার্যকারিতা । আপনি এটিকে সমস্ত ধরণের জিনিস প্রচার এবং ক্ষয় করতে ব্যবহার করতে পারেন

একটি অঙ্ককে পূর্ণসংখ্যায় রূপান্তর করা

+AnEnumeratorValue

এবং আপনার গণকের মান যা আগে এর গণনা টাইপ ছিল এখন সঠিক পূর্ণসংখ্যার টাইপ রয়েছে যা এর মানটি ফিট করতে পারে। ম্যানুয়ালি, আপনি খুব সহজেই এই ধরণের জানতেন! উদাহরণস্বরূপ এটি প্রয়োজন যখন আপনি নিজের গণনার জন্য একটি ওভারলোডেড অপারেটরটি প্রয়োগ করতে চান।

একটি চলক থেকে মান পেতে

আপনাকে এমন একটি ক্লাস ব্যবহার করতে হবে যা ক্লাস সংজ্ঞা ছাড়াই একটি শ্রেণির স্ট্যাটিক ইনিশিয়ালাইজার ব্যবহার করে তবে কখনও কখনও এটি লিঙ্ক করতে ব্যর্থ হয়? অপারেটর তার ধরণের উপর নির্ভরযোগ্যতা বা নির্ভরতা না তৈরি করে একটি অস্থায়ী তৈরি করতে সহায়তা করতে পারে

struct Foo {
  static int const value = 42;
};

// This does something interesting...
template<typename T>
void f(T const&);

int main() {
  // fails to link - tries to get the address of "Foo::value"!
  f(Foo::value);

  // works - pass a temporary value
  f(+Foo::value);
}

পয়েন্টারের কাছে একটি অ্যারে ক্ষয় করুন

আপনি কি কোনও ফাংশনে দুটি পয়েন্টার পাস করতে চান তবে এটি কার্যকর হবে না? অপারেটর সাহায্য করতে পারে

// This does something interesting...
template<typename T>
void f(T const& a, T const& b);

int main() {
  int a[2];
  int b[3];
  f(a, b); // won't work! different values for "T"!
  f(+a, +b); // works! T is "int*" both time
}

61

রেফারেন্সগুলিতে আবদ্ধ অস্থায়ীদের জীবনকাল এমন একটি যা খুব কম লোকই জানেন know বা কমপক্ষে এটি আমার প্রিয় সি ++ জ্ঞানের টুকরো যা বেশিরভাগ লোকেরা জানেন না।

const MyClass& x = MyClass(); // temporary exists as long as x is in scope

3
তুমি কি বিস্তারিত বলতে পারো? যেমন আপনি কেবল
টিজ

8
ScopeGuard ( ddj.com/cpp/184403758 ) একটি দুর্দান্ত উদাহরণ যা এই বৈশিষ্ট্যটি উপকৃত করে।
এমএসএল

2
আমি জোসেফ গারভিনের সাথে আছি। আমাদের আলোকিত করুন।
পিটার মর্টেনসেন

আমি শুধু মন্তব্যে করেছিলাম। তদ্ব্যতীত, কনস্টের রেফারেন্স প্যারামিটার ব্যবহার করা এটি একটি প্রাকৃতিক ফলাফল।
এমএসএন 23


52

একটি দুর্দান্ত বৈশিষ্ট্য যা প্রায়শই ব্যবহৃত হয় না তা হ'ল ফাংশন-ওয়াইড ট্রাই-ক্যাচ ব্লক:

int Function()
try
{
   // do something here
   return 42;
}
catch(...)
{
   return -1;
}

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


আমি মনে করি না আপনি returnফাংশন ট্রাই ধরার ব্লক থেকে কেবল পুনর্নবীকরণ করতে পারেন।
কনস্টান্টিন

আমি কেবল উপরেরটি সংকলনের চেষ্টা করেছি এবং এটি কোনও সতর্কতা দেয়নি। আমি মনে করি উপরের উদাহরণটি কাজ করে।
ভিভিডোস

7
রিটার্ন শুধুমাত্র নির্মাণকারীদের জন্য নিষিদ্ধ। কনস্ট্রাক্টরের ফাংশন ট্রাই ব্লকটি বেস এবং সদস্যদের সূচনা করার সময় ত্রুটিগুলি ধরবে (একমাত্র ক্ষেত্রে যেখানে ফাংশন ট্রাই ব্লক ফাংশনের অভ্যন্তরে চেষ্টা করার চেয়ে কিছু আলাদা করে); পুনরায় নিক্ষেপ না করার ফলে একটি অসম্পূর্ণ অবজেক্ট তৈরি হবে।
puetzk

হ্যাঁ. এটি খুব দরকারী। আমি ব্যতিক্রমগুলি ধরার জন্য এবং HRESULTS ফেরত দেওয়ার জন্য ম্যাক্রোস BEGIN_COM_METHOD এবং END_COM_METHOD লিখেছিলাম যাতে ব্যতিক্রমগুলি কোনও COM ইন্টারফেস প্রয়োগকারী কোনও শ্রেণীর বাইরে না চলে। এটা ভাল কাজ করে।
স্কট ল্যাংহাম

3
@ পুইটজ্কের নির্দেশ অনুসারে, কোনও নির্মাণকারীর সূচনা তালিকার কোনও কিছু যেমন ব্যাস ক্লাসের কনস্ট্রাক্টর বা ডেটা মেম্বারদের রেখে দেওয়া ব্যতিক্রমগুলি পরিচালনা করার একমাত্র উপায় is
anton.burger

44

অনেকে identity/ idরূপান্তরটি জানেন , তবে এটি টেম্পলেট-না-করা মামলার জন্য একটি দুর্দান্ত ব্যবহারের ঘড়ি রয়েছে: সহজেই লেখার ঘোষণা:

// void (*f)(); // same
id<void()>::type *f;

// void (*f(void(*p)()))(int); // same
id<void(int)>::type *f(id<void()>::type *p);

// int (*p)[2] = new int[10][2]; // same
id<int[2]>::type *p = new int[10][2];

// void (C::*p)(int) = 0; // same
id<void(int)>::type C::*p = 0;

এটি সি ++ ডিক্লোরেশনগুলি ব্যাপকভাবে ডিক্রিপ্টিংয়ে সহায়তা করে!

// boost::identity is pretty much the same
template<typename T> 
struct id { typedef T type; };

আকর্ষণীয়, তবে প্রাথমিকভাবে আমার সেই সংজ্ঞাগুলির কয়েকটি পড়তে আরও সমস্যা হয়েছিল। সি ++ ডিক্লেয়ারেশনের সাথে অভ্যন্তরীণ সমস্যার সমাধানের আরও একটি উপায় হ'ল কিছু টেম্পলেট প্রকারের নাম লিখুন: template<typename Ret,typename... Args> using function = Ret (Args...); template<typename T> using pointer = *T;-> pointer<function<void,int>> f(pointer<function<void,void>>);বা pointer<void(int)> f(pointer<void()>);বাfunction<pointer<function<void,int>>,pointer<function<void,void>>> f;
বেমস 5

42

একটি গোপন বৈশিষ্ট্য হ'ল আপনি যদি একটি শর্তের মধ্যে ভেরিয়েবল সংজ্ঞায়িত করতে পারেন এবং এর ব্যাপ্তি কেবলমাত্র if এবং এর অন্য ব্লকগুলিতে বিস্তৃত হবে:

if(int * p = getPointer()) {
    // do something
}

কিছু ম্যাক্রো এটি ব্যবহার করে, উদাহরণস্বরূপ কিছু "লকড" স্কোপ সরবরাহ করার জন্য:

struct MutexLocker { 
    MutexLocker(Mutex&);
    ~MutexLocker(); 
    operator bool() const { return false; } 
private:
    Mutex &m;
};

#define locked(mutex) if(MutexLocker const& lock = MutexLocker(mutex)) {} else 

void someCriticalPath() {
    locked(myLocker) { /* ... */ }
}

এছাড়াও BOOST_FOREach হুডের নীচে এটি ব্যবহার করে। এটি সম্পূর্ণ করার জন্য, এটি কেবলমাত্র একটি ক্ষেত্রেই সম্ভব নয়, একটি স্যুইচও সম্ভব:

switch(int value = getIt()) {
    // ...
}

এবং কিছুক্ষণের মধ্যে লুপ:

while(SomeThing t = getSomeThing()) {
    // ...
}

(এবং শর্তের জন্যও) তবে আমি খুব বেশি নিশ্চিত নই যে এগুলি সমস্ত কার্যকর কিনা :)


ঝরঝরে! আমি কখনই জানতাম না যে আপনি এটি করতে পারবেন ... ত্রুটি ফেরতের মানগুলির সাথে কোড লেখার সময় এটি কিছু ঝামেলা বাঁচবে (এবং করবে)। এই ফর্মটিতে কেবল! = 0 এর পরিবর্তে শর্তাধীন থাকার কোনও উপায় আছে কি? যদি ((int r = func ()) <0) কাজ করছে বলে মনে হচ্ছে না ...
puetzk

puetzk, নেই। তবে আনন্দিত আপনি এটি পছন্দ করেছেন :)
জোহানেস স্কাউব - 11:59

4
@ ফ্রেরিচ, সি কোডে এটি মোটেই সম্ভব নয়। আমার মনে হয় আপনি ভাবছেন if((a = f()) == b) ...তবে এই উত্তরটি আসলে শর্তে পরিবর্তনশীল হিসাবে ঘোষণা করে।
জোহানেস স্কাউব - 17

1
@Angry এটি খুব আলাদা, কারণ পরিবর্তনশীল ঘোষণাটি সরাসরি তার বুলিয়ান মানটির জন্য পরীক্ষা করা হয়। ফর-লুপগুলিতে একটি ম্যাপিংও রয়েছে, যা দেখে মনে হচ্ছে for(...; int i = foo(); ) ...;এটি যতক্ষণ iসত্য হয় ততক্ষণে এটি প্রতিবারই শুরু করে দেহের মধ্যে দিয়ে যাবে । আপনি যে লুপটি দেখান তা কেবল একটি পরিবর্তনীয় ঘোষণা প্রদর্শন করে তবে পরিবর্তনশীল ঘোষণা নয় যা একযোগে শর্ত হিসাবে কাজ করে :)
জোহানেস স্কাউব - লিটব

5
খুব ভাল, আপনি যদি এই বৈশিষ্ট্যটির জন্য অভিযুক্ত ব্যবহারটি গতিশীল পয়েন্টার কাস্টের জন্য না করেন তবে আমি বিশ্বাস করি।
মিমোকনি

29

অপারেটরকে ওভারলোডগুলি কল করা থেকে কমা অপারেটরটি আটকানো

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

for(T i, j; can_continue(i, j); ++i, void(), ++j)
  do_code(i, j);

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


আমি আমার ওভারকিল অভিব্যক্তি উপেক্ষাকারীকে শেষ করতে এটি ব্যবহার করেছি । :)
GManNickG

28

কনস্ট্রাক্টরে অ্যারে ইনিশিয়ালাইজেশন। উদাহরণস্বরূপ কোনও শ্রেণিতে যদি আমাদের মতো একটি অ্যারে থাকে int:

class clName
{
  clName();
  int a[10];
};

কনস্ট্রাক্টরে আমরা অ্যারের সমস্ত উপাদান এর ডিফল্ট (এখানে অ্যারের সমস্ত উপাদান শূন্যে) হিসাবে শুরু করতে পারি:

clName::clName() : a()
{
}

6
আপনি যে কোনও অ্যারে দিয়ে এটি করতে পারেন।
পোটোসওয়টার

@ পোটাটোসওয়টার: সবচেয়ে বেশি ভেক্সিং পার্সের কারণে দেখতে দেখতে তার চেয়ে শক্ত। আমি অন্য কোনও জায়গায় এটি করা যায় তা ভাবতে পারি না, সম্ভবত কোনও ফেরতের মান
বাদে

অ্যারের ধরণটি যদি শ্রেণীর ধরণের হয় তবে এটির সঠিক প্রয়োজন নেই?
টমাস এডিং

27

ওহ, আমি পরিবর্তে পোষা ঘৃণ্য একটি তালিকা নিয়ে আসতে পারি:

  • যদি আপনি বহুবিধভাবে ব্যবহার করতে চান তবে ধ্বংসকারীদের ভার্চুয়াল হওয়া দরকার
  • কখনও কখনও সদস্যগণ ডিফল্ট দ্বারা সূচনা করা হয়, কখনও কখনও তারা হয় না
  • স্থানীয় ক্লাজগুলি টেমপ্লেট প্যারামিটার হিসাবে ব্যবহার করা যায় না (এগুলিকে কম দরকারী করে তোলে)
  • ব্যতিক্রম নির্দিষ্টকরণকারী: দরকারী দেখুন, কিন্তু না
  • ফাংশন ওভারলোডগুলি বিভিন্ন স্বাক্ষর সহ বেস শ্রেণির ফাংশনগুলি লুকায়।
  • আন্তর্জাতিকীকরণের জন্য কোনও কার্যকর মানসম্মতকরণ নেই (পোর্টেবল স্ট্যান্ডার্ড প্রশস্ত চরসেট, যে কেউ? আমাদের C ++ 0x অবধি অপেক্ষা করতে হবে)

প্লাস পাশ দিয়ে

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

16
পোষা বিদ্বেষ: সি ++ অ্যাপ্লিকেশনগুলির জন্য কোনও সংজ্ঞায়িত এবিআই নয়, সি ব্যবহার করে যা সবাই ব্যবহার করে কারণ প্রতিটি ভাষা সি ফাংশন কল করার গ্যারান্টি দিতে পারে, কেউ সি ++ এর জন্য একই কাজ করতে পারে না।
gbjbaanb

8
পলিমॉর্ফিকালি ধ্বংস করতে চাইলে কেবল ধ্বংসকারীদের ভার্চুয়াল হওয়া দরকার, যা প্রথম দিক থেকে কিছুটা সূক্ষ্মভাবে পৃথক।
ডেভিড রদ্রিগেজ - ড্রিবিস

2
সি ++ 0x এর সাথে স্থানীয় প্রকারগুলি টেম্পলেট প্যারামিটার হিসাবে ব্যবহার করা যেতে পারে।
tstenner

1
সি ++ 0 এক্স এর সাহায্যে ডিস্ট্রাক্টরগুলি ভার্চুয়াল হতে পারে যদি বস্তুর কোনও ভার্চুয়াল ফাংশন থাকে (যেমন একটি vtable)।
ম্যাক

এনআরভিও ভুলে যাবেন না, এবং অবশ্যই কোনও অপ্টিমাইজেশন অনুমোদিত হয় যতক্ষণ না এটি প্রোগ্রামের আউটপুট
জেকে

26

আপনি অনির্ধারিত আচরণ ছাড়াই এবং প্রত্যাশিত শব্দার্থকতা সহ সুরক্ষিত ডেটা এবং কোনও শ্রেণীর ফাংশন সদস্য অ্যাক্সেস করতে পারেন। কিভাবে দেখুন পড়ুন। এই সম্পর্কে ত্রুটি প্রতিবেদনটি পড়ুন ।

সাধারণত, সি ++ আপনাকে শ্রেণীর অবজেক্টের অ স্থিতিশীল সুরক্ষিত সদস্যদের অ্যাক্সেস করতে নিষেধ করে, এমনকি সেই শ্রেণিটি যদি আপনার বেস শ্রেণি হয়

struct A {
protected:
    int a;
};

struct B : A {
    // error: can't access protected member
    static int get(A &x) { return x.a; }
};

struct C : A { };

এটি নিষিদ্ধ: আপনি এবং সংকলক জানেন না যে রেফারেন্সটি আসলে কী নির্দেশ করে। এটি কোনও Cঅবজেক্ট হতে পারে , যেখানে শ্রেণীর Bকোনও ডেটা বা ব্যবসা সম্পর্কিত ধারণা থাকে না। এই জাতীয় অ্যাক্সেস কেবল তখনই মঞ্জুর করা হয় যখন xকোনও উদ্ভূত শ্রেণীর বা এটি থেকে প্রাপ্ত একটির সাথে সম্পর্কিত। এবং এটি যেকোন সুরক্ষিত সদস্যকে কেবল "থ্রো-অ্যাও" ক্লাস তৈরি করে সদস্যদের পড়ার জন্য নির্বিচারে কোডের টুকরোটিকে অনুমতি দিতে পারে, উদাহরণস্বরূপ std::stack:

void f(std::stack<int> &s) {
    // now, let's decide to mess with that stack!
    struct pillager : std::stack<int> {
        static std::deque<int> &get(std::stack<int> &s) {
            // error: stack<int>::c is protected
            return s.c;
        }
    };

    // haha, now let's inspect the stack's middle elements!
    std::deque<int> &d = pillager::get(s);
}

অবশ্যই, আপনি দেখছেন যে এর ফলে খুব বেশি ক্ষতি হতে পারে। তবে এখন, সদস্য পয়েন্টারগুলি এই সুরক্ষাটিকে অবরুদ্ধ করার অনুমতি দেয়! মূল বক্তব্যটি হ'ল সদস্য পয়েন্টারের ধরণটি সেই শ্রেণীর সাথে আবদ্ধ যার মধ্যে প্রকৃতপক্ষে বলা সদস্য থাকে - ঠিকানাটি নেওয়ার সময় আপনি যে ক্লাসটি নির্দিষ্ট করেছিলেন তা নয় । এটি আমাদের চেক অবরুদ্ধ করতে দেয়

struct A {
protected:
    int a;
};

struct B : A {
    // valid: *can* access protected member
    static int get(A &x) { return x.*(&B::a); }
};

struct C : A { };

এবং অবশ্যই এটি std::stackউদাহরণ সহ কাজ করে ।

void f(std::stack<int> &s) {
    // now, let's decide to mess with that stack!
    struct pillager : std::stack<int> {
        static std::deque<int> &get(std::stack<int> &s) {
            return s.*(pillager::c);
        }
    };

    // haha, now let's inspect the stack's middle elements!
    std::deque<int> &d = pillager::get(s);
}

উদ্ভূত শ্রেণিতে একটি ব্যবহারের ঘোষণার মাধ্যমে এটি আরও সহজ হতে চলেছে, যা সদস্যের নামটি পাবলিক করে এবং বেস শ্রেণীর সদস্যকে বোঝায়।

void f(std::stack<int> &s) {
    // now, let's decide to mess with that stack!
    struct pillager : std::stack<int> {
        using std::stack<int>::c;
    };

    // haha, now let's inspect the stack's middle elements!
    std::deque<int> &d = s.*(&pillager::c);
}


26

আর একটি লুকানো বৈশিষ্ট্য হ'ল আপনি শ্রেণিক অবজেক্টগুলিকে কল করতে পারেন যা ফাংশন পয়েন্টার বা রেফারেন্সে রূপান্তর করতে পারে। ওভারলোড রেজোলিউশন তাদের ফলস্বরূপ করা হয়, এবং যুক্তিগুলি পুরোপুরি এগিয়ে দেওয়া হয়।

template<typename Func1, typename Func2>
class callable {
  Func1 *m_f1;
  Func2 *m_f2;

public:
  callable(Func1 *f1, Func2 *f2):m_f1(f1), m_f2(f2) { }
  operator Func1*() { return m_f1; }
  operator Func2*() { return m_f2; }
};

void foo(int i) { std::cout << "foo: " << i << std::endl; }
void bar(long il) { std::cout << "bar: " << il << std::endl; }

int main() {
  callable<void(int), void(long)> c(foo, bar);
  c(42); // calls foo
  c(42L); // calls bar
}

এগুলিকে "সারোগেট কল ফাংশন" বলা হয়।


1
যখন আপনি বলেন যে ওভারলোড রেজোলিউশন তাদের ফলাফলের ভিত্তিতে করা হয়ে থাকে, আপনি কি বোঝাতে চেয়েছেন যে এটি আসলে এটিকে উভয় ফান্টেক্টরে রূপান্তরিত করে এবং তারপরে ওভারলোড রেজোলিউশন করে? আমি অপারেটর Func1 * () এবং অপারেটর Func2 * () তে কিছু মুদ্রণের চেষ্টা করেছি, তবে কোন রূপান্তরকারী অপারেটরকে প্রার্থনা করতে হবে তা নির্ধারণ করার পরে এটি সঠিকটি বেছে নেবে বলে মনে হচ্ছে।
নেভিগেটর

3
@ ন্যাভিগেটর, হ্যাঁ এটিকে ধারণামূলকভাবে উভয়তে রূপান্তরিত করে এবং তারপরে সেরাটিকে বেছে নিয়েছে। এগুলি আসলে তাদের কল করার দরকার নেই, কারণ তারা ইতিমধ্যে কী ফল দেবে ফলাফল-টাইপ থেকে তা জানে। প্রকৃত কলটি করা হয় যখন এটি শেষ হয়ে যায় কী চয়ন করা হয়েছিল।
জোহানেস স্কাউব -

26

লুকানো বৈশিষ্ট্য:

  1. খাঁটি ভার্চুয়াল ফাংশনগুলির বাস্তবায়ন থাকতে পারে। সাধারণ উদাহরণ, খাঁটি ভার্চুয়াল ডেস্ট্রাক্টর।
  2. যদি কোনও ফাংশন তার ব্যতিক্রম বিশদগুলিতে তালিকাভুক্ত নয় এমন একটি ব্যতিক্রম ছুঁড়ে ফেলে তবে ফাংশনটির std::bad_exceptionতার ব্যতিক্রমের নির্দিষ্টকরণে ব্যতিক্রমটি রূপান্তরিত হয় std::bad_exceptionএবং স্বয়ংক্রিয়ভাবে নিক্ষিপ্ত হয়। এইভাবে আপনি কমপক্ষে জানতে পারবেন যে একটি bad_exceptionনিক্ষেপ করা হয়েছিল। এখানে আরও পড়ুন ।

  3. ফাংশন চেষ্টা ব্লক

  4. শ্রেণিবদ্ধ টেম্পলেটগুলিতে টাইপডেফগুলি বিঘ্নিত করতে টেমপ্লেট কীওয়ার্ড। যদি কোনও সদস্য টেমপ্লেট বিশেষীর নাম প্রদর্শিত হয় ক এর পরে. , ->অথবা ::অপারেটর, এবং যে নাম স্পষ্টভাবে যোগ্যতাসম্পন্ন টেমপ্লেট পরামিতি, অভিব্যক্তি টেমপ্লেট দিয়ে উপসর্গ সদস্য টেমপ্লেট নাম আছে। এখানে আরও পড়ুন ।

  5. ফাংশন প্যারামিটার ডিফল্ট রানটাইম সময়ে পরিবর্তন করা যেতে পারে। আরও পড়ুনএখানে

  6. A[i] হিসাবে ভাল হিসাবে কাজ করে i[A]

  7. একটি শ্রেণীর অস্থায়ী উদাহরণগুলি সংশোধন করা যেতে পারে! কোনও অ-স্থায়ী সদস্য ফাংশনটি একটি অস্থায়ী অবজেক্টে আহ্বান করা যেতে পারে। উদাহরণ স্বরূপ:

    struct Bar {
      void modify() {}
    }
    int main (void) {
      Bar().modify();   /* non-const function invoked on a temporary. */
    }

    আরও পড়ুন এখানে

  8. যদি দুটি ভিন্ন ধরণের আগে এবং :তারারারি ( ?:) অপারেটরের এক্সপ্রেশনটিতে উপস্থিত থাকে, তবে এক্সপ্রেশনটির ফলে প্রাপ্ত প্রকারটিই দুটির মধ্যে সবচেয়ে সাধারণ। উদাহরণ স্বরূপ:

    void foo (int) {}
    void foo (double) {}
    struct X {
      X (double d = 0.0) {}
    };
    void foo (X) {} 
    
    int main(void) {
      int i = 1;
      foo(i ? 0 : 0.0); // calls foo(double)
      X x;
      foo(i ? 0.0 : x);  // calls foo(X)
    }

পি বাবা: এ [আমি] == * (এ + আই) == * (আই + এ) == আই [এ]
আবলেঙ্কি

আমি যাত্রাটি পাই, এটির ঠিক অর্থ এই যে [] এর নিজস্ব কোনও শব্দার্থক মূল্য নেই এবং এটি কেবলমাত্র ম্যাক্রো-স্টাইল প্রতিস্থাপনের সমতুল্য যেখানে "x [y]" "" (* ((x)) + (y এর সাথে প্রতিস্থাপিত হয়েছে ))) "। আমি যা আশা করেছিলাম তা মোটেই নয়। আমি কেন এইভাবে সংজ্ঞায়িত হই তা অবাক করি।
পি বাবা 3

সি
jmucchiello

2
আপনার প্রথম বিষয় সম্পর্কে: একটি নির্দিষ্ট ক্ষেত্রে রয়েছে যেখানে আপনাকে খাঁটি ভার্চুয়াল ফাংশন প্রয়োগ করতে হবে: খাঁটি ভার্চুয়াল ডেস্ট্রাক্টর।
ফ্রেরিচ রাবাব

24

map::operator[]কী অনুপস্থিত থাকলে এন্ট্রি তৈরি করে এবং ডিফল্ট-নির্মিত-নির্ধারিত প্রবেশ মূল্যকে রেফারেন্স দেয়। সুতরাং আপনি লিখতে পারেন:

map<int, string> m;
string& s = m[42]; // no need for map::find()
if (s.empty()) { // assuming we never store empty values in m
  s.assign(...);
}
cout << s;

কতজন সি ++ প্রোগ্রামার এটি জানেন না তাতে আমি অবাক হয়েছি।


11
এবং বিপরীত প্রান্তে আপনি
কোনও কনস্টের

2
নিকের জন্য +1, লোকেরা জানতে না পারলে পাগল হতে পারে .find()
LiraNuna

বা " const map::operator[]ত্রুটি বার্তা উত্পন্ন করে"
কেবল

2
ভাষার কোনও বৈশিষ্ট্য নয়, এটি স্ট্যান্ডার্ড টেম্পলেট লাইব্রেরির বৈশিষ্ট্য। এটিও বেশ সুস্পষ্ট, যেহেতু অপারেটর [] বৈধ উল্লেখ প্রেরণ করে।
রামন জারাজুয়া বি

2
আমাকে সি # তে কিছু সময়ের জন্য মানচিত্র ব্যবহার করতে হয়েছিল, যেখানে মানচিত্রগুলি সেভাবে আচরণ করে না, যাতে এটি বুঝতে পারে যে এটি একটি বৈশিষ্ট্য। আমি ভেবেছিলাম এটি ব্যবহার করার চেয়ে আমি এতে বেশি বিরক্ত হয়েছি, তবে মনে হচ্ছে আমি ভুল ছিল। আমি এটি সি # এ মিস করছি।
এসবিআই

20

নামবিহীন নেমস্পেসে ফাংশন বা ভেরিয়েবলগুলি রাখলে staticসেগুলি ফাইলের সুযোগের মধ্যে সীমাবদ্ধ রাখার জন্য ব্যবহারকে হ্রাস করে।



@ পোটাটো: পুরাতন মন্তব্য, আমি জানি, তবে মানকটি বলে যে নামহীন স্থানের ক্ষেত্রে স্ট্যাটিকের ব্যবহার অবজ্ঞা করা হয়েছে, নামবিহীন নেমস্পেসের অগ্রাধিকার সহ।
GManNickG

@ জিএমান: কোনও সমস্যা নেই, আমি মনে করি না এসও পৃষ্ঠাগুলি সত্যিই "মারা যায়"। কেবল গল্পের উভয় পক্ষেই, staticবিশ্বব্যাপী সুযোগে কোনওভাবেই হ্রাস পাওয়া যায় না। (রেফারেন্সের জন্য: C ++ 03 §D.2)
পটোটোওয়াত্তর

আহ, আরও পড়ার সময়, "গ্লোবাল নেমস্পেসে ঘোষিত একটি নামের গ্লোবাল নেমস্পেসের সুযোগ রয়েছে (এটি বৈশ্বিক সুযোগও বলা হয়)"। এর মানে কি আসলে?
পোটোসওয়টার

@ পোটাটো: হ্যাঁ :) staticব্যবহার কেবলমাত্র শ্রেণিবদ্ধ বা ফাংশনের মধ্যে ব্যবহার করা উচিত।
GManNickG

19

ক্লাস টেম্পলেটগুলিতে সাধারণ বন্ধু ফাংশন সংজ্ঞায়িত করার জন্য বিশেষ মনোযোগ দেওয়া দরকার:

template <typename T> 
class Creator { 
    friend void appear() {  // a new function ::appear(), but it doesn't 
                           // exist until Creator is instantiated 
    } 
};
Creator<void> miracle;  // ::appear() is created at this point 
Creator<double> oops;   // ERROR: ::appear() is created a second time! 

এই উদাহরণে, দুটি পৃথক তাত্পর্য দুটি অভিন্ন সংজ্ঞা তৈরি করে - এটি ওডিআর এর সরাসরি লঙ্ঘন

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

template <typename T> 
class Creator { 
    friend void feed(Creator<T>*){  // every T generates a different 
                                   // function ::feed() 
    } 
}; 

Creator<void> one;     // generates ::feed(Creator<void>*) 
Creator<double> two;   // generates ::feed(Creator<double>*) 

দাবি অস্বীকার: আমি এই বিভাগটি সি ++ টেম্পলেটগুলি থেকে আটকিয়েছি : সম্পূর্ণ গাইড / বিভাগ 8.4


18

অকার্যকর ফাংশন অকার্যকর মান ফিরে আসতে পারে

অল্প পরিচিত, তবে নিম্নলিখিত কোডটি ঠিক আছে

void f() { }
void g() { return f(); }

নিম্নলিখিত অদ্ভুত চেহারা এক হিসাবে ভাল

void f() { return (void)"i'm discarded"; }

এ সম্পর্কে জেনে আপনি কিছু ক্ষেত্রে সুবিধা নিতে পারেন। একটি উদাহরণ: voidফাংশনগুলি কোনও মান ফেরত দিতে পারে না তবে আপনি কেবল কিছুই ফিরিয়ে দিতে পারবেন না কারণ এগুলি শূন্যতার সাথে ইনস্ট্যান্ট করা যেতে পারে। স্থানীয় ভেরিয়েবলে মানটি সংরক্ষণের পরিবর্তে, যার ফলে ত্রুটি ঘটবে void, কেবল একটি মান সরাসরি করুন return

template<typename T>
struct sample {
  // assume f<T> may return void
  T dosomething() { return f<T>(); }

  // better than T t = f<T>(); /* ... */ return t; !
};

17

স্ট্রিংয়ের ভেক্টরে একটি ফাইল পড়ুন:

 vector<string> V;
 copy(istream_iterator<string>(cin), istream_iterator<string>(),
     back_inserter(V));

istream_iterator


8
বা: ভেক্টর <স্ট্রিং> ভি ((istream_iterator <string> (cin)), istream_iterator <string>);
আঙ্কেলবেন্স

5
আপনার অর্থ vector<string> V((istream_iterator<string>(cin)), istream_iterator<string>());- দ্বিতীয়
পরমের

1
এটি সত্যই কোনও লুকানো সি ++ বৈশিষ্ট্য নয়। একটি এসটিএল বৈশিষ্ট্য আরও। এসটিএল! = একটি ভাষা
নিক বেডফোর্ড

14

আপনি বিটফিল্ড টেমপ্লেট করতে পারেন।

template <size_t X, size_t Y>
struct bitfield
{
    char left  : X;
    char right : Y;
};

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


1
যেখানে আমি সম্প্রতি এন-বিট গাণিতিক জন্য এটি সুপারিশ এখানে দেখুন: stackoverflow.com/questions/8309538/...
sehe

14

যে কোনও প্রোগ্রামিং ভাষার অন্যতম আকর্ষণীয় ব্যাকরণ।

এই তিনটি জিনিস এক সাথে সম্পর্কিত, এবং দুটি সম্পূর্ণ আলাদা কিছু ...

SomeType t = u;
SomeType t(u);
SomeType t();
SomeType t;
SomeType t(SomeType(u));

সকল কিন্তু তৃতীয় ও পঞ্চম একটি সংজ্ঞায়িত SomeTypeস্ট্যাক বস্তু এবং এটি আরম্ভ (সঙ্গে uএকটি প্রথম দুই ক্ষেত্রে, এবং চতুর্থ ডিফল্ট কন্সট্রাকটর। তৃতীয় একটি ফাংশন যে কোন প্যারামিটার এবং আয় লাগে ঘোষণা করা হয় SomeType। পঞ্চম একভাবে ঘোষণা করা হয় একটি ফাংশন যা SomeTypeনামের ধরণের মান অনুসারে একটি পরামিতি নেয় u


1 ম এবং 2 য় মধ্যে কোন পার্থক্য আছে? যদিও, আমি জানি তারা উভয়ই সূচনা।
üzgür

নিয়ন্ত্রক: আমি তা মনে করি না। দু'জনই অনুলিপি-কন্সট্রাক্টরকে কল করবে, যদিও প্রথম নিয়োগটি অপারেটর অপারেটরের মতো দেখায়, এটি সত্যই অনুলিপি-নির্মাণকারী।
আবেলেনকি

1
আপনি যদি সোমটাইপের থেকে আলাদা ধরণের হন তবে প্রথমে রূপান্তর কনস্ট্রাক্টরকে প্রথমে কল করুন এবং তারপরে অনুলিপি করুন, অন্যদিকে কেবল রূপান্তর কনস্ট্রাক্টরকে কল করবে।
অন্ধকার

3
1 ম হ'ল কনস্ট্রাক্টর এর অন্তর্নিহিত কল, 2 য়টি সুস্পষ্ট কল। পার্থক্যটি দেখতে নিম্নলিখিত কোডটি দেখুন: # অন্তর্ভুক্ত <iostream> শ্রেণি এসএসএস {সর্বজনীন: স্পষ্টত sss (অন্তর্) {স্টাড :: কোট << "ইনট" << স্টাডি :: এন্ডল; }; sss (ডাবল) {স্টাড :: কোট << "ডাবল" << স্টাড :: এন্ডল; }; }; int main () {sss ddd (7); // কল ইন্ট কনস্ট্রাক্টর এসএসএস xxx = 7; // ডাবল কনস্ট্রাক্টর রিটার্ন কল 0; }
কিরিল ভি লিয়াডভিনস্কি

সত্য - নির্মাণকারীকে সুস্পষ্টভাবে ঘোষণা করা হলে প্রথম লাইনটি কাজ করবে না।
অন্ধকার

12

ফরোয়ার্ড ঘোষণা থেকে মুক্তি পাওয়া:

struct global
{
     void main()
     {
           a = 1;
           b();
     }
     int a;
     void b(){}
}
singleton;

সাথে সুইচ-বিবৃতি রচনা?: অপারেটর:

string result = 
    a==0 ? "zero" :
    a==1 ? "one" :
    a==2 ? "two" :
    0;

একক লাইনে সবকিছু করা:

void a();
int b();
float c = (a(),b(),1.0f);

মেমসেট ছাড়াই জিরোং স্ট্রাক্ট:

FStruct s = {0};

সাধারনকরণ / মোড়ক কোণ- এবং সময়-মান:

int angle = (short)((+180+30)*65536/360) * 360/65536; //==-150

রেফারেন্স উল্লেখ:

struct ref
{
   int& r;
   ref(int& r):r(r){}
};
int b;
ref a(b);
int c;
*(int**)&a = &c;

2
FStruct s = {};এমনকি আরও খাটো।
কনস্টান্টিন

শেষ উদাহরণে এটি সহজ হবে: ক (); খ (); ভাসা সি = 1.0f;
জিফ্রে

2
এই সিনট্যাক্স "ফ্লোট সি = (এ (), বি (), 1.0 ফ);" অ্যাসিগমেন্ট-অপারেশন ("গ" এর অ্যাসিগমেন্ট) উচ্চারণের জন্য দরকারী। অ্যাসিগমেন্ট-অপারেশনগুলি প্রোগ্রামিংয়ে গুরুত্বপূর্ণ কারণ তারা অবহিত আইএমও হওয়ার সম্ভাবনা কম। কেন জানি না, ফাংশনাল প্রোগ্রামিংয়ের সাথে এমন কিছু হতে পারে যেখানে প্রতিটি ফ্রেমকে প্রোগ্রামের স্থিতি দেওয়া হয়। পুনশ্চ. এবং না, "int d = (11,22,1.0f)" "1" এর সমান হবে। VS2008 দিয়ে এক মিনিট আগে পরীক্ষা করা হয়েছিল।
আয়ারেপ

2
+1 আপনার কল করা উচিত নয় main? আমি প্রস্তাব দিয়েছি global().main();এবং কেবল সিঙ্গলটনের কথা ভুলে যাব ( আপনি কেবলমাত্র অস্থায়ী সাথে কাজ করতে পারেন, যা তার আজীবন প্রসারিত হয়ে
উঠবে

1
আমি সন্দেহ রেফারেন্স নির্ধারণযোগ্য। আমি যদিও ঘোষণাটি ছাড়ার জন্য স্ট্রাক্টটি পছন্দ করি।
টমাস এডিং

12

ত্রিশী শর্তসাপেক্ষ অপারেটরের ?:"দ্বিতীয়" এবং "অনানুষ্ঠানিকভাবে কথা বলা" প্রকারের জন্য তার দ্বিতীয় এবং তৃতীয় অপারেন্ড দরকার। তবে এই প্রয়োজনীয়তার একটি ব্যতিক্রম রয়েছে (পাং উদ্দেশ্যে): দ্বিতীয় বা তৃতীয় অপারেন্ড হয় নিক্ষেপ এক্সপ্রেশন (যা টাইপযুক্ত) হতে পারেvoid অন্য অপারেন্ডের ধরণের নির্বিশেষে, ) ।

অন্য কথায়, একটি ব্যবহার নিম্নলিখিত pefrectly বৈধ সি ++ এক্সপ্রেশন লিখতে পারেন ?:অপারেটর

i = a > b ? a : throw something();

বিটিডাব্লু, থ্রো এক্সপ্রেশনটি আসলে একটি অভিব্যক্তি (টাইপের void) এবং স্টেটমেন্ট নয় এটি সি ++ ভাষার আরও একটি অল্প-পরিচিত বৈশিষ্ট্য। এর অর্থ অন্যান্য জিনিসগুলির মধ্যে রয়েছে যে নিম্নলিখিত কোডটি পুরোপুরি বৈধ

void foo()
{
  return throw something();
}

যদিও এটি এইভাবে করার পক্ষে খুব বেশি কিছু নেই (সম্ভবত কিছু জেনেরিক টেম্পলেট কোডে এটি কার্যকর হতে পারে)।


এটি মূল্যবান কিসের জন্য, নীলের এই সম্পর্কে একটি প্রশ্ন রয়েছে: কেবল অতিরিক্ত তথ্যের জন্য stackoverflow.com/questions/1212978/… ,।
GManNickG

12

আধিপত্য বিধি কার্যকর, কিন্তু অল্প পরিচিত। এটি বলে যে বেস-ক্লাসের জালির মাধ্যমে কোনও অ-অনন্য পথের মধ্যেও, যদি কোনও সদস্য ভার্চুয়াল বেস-শ্রেণীর অন্তর্ভুক্ত থাকে তবে আংশিকভাবে লুকানো সদস্যের নাম অনুসন্ধান অনন্য:

struct A { void f() { } };

struct B : virtual A { void f() { cout << "B!"; } };
struct C : virtual A { };

// name-lookup sees B::f and A::f, but B::f dominates over A::f !
struct D : B, C { void g() { f(); } };

অ্যালাইনমেন্ট-সমর্থন বাস্তবায়নের জন্য আমি এটি ব্যবহার করেছি যা আধিপত্য বিধি দ্বারা স্বয়ংক্রিয়ভাবে কঠোর সারিবদ্ধকরণ খুঁজে বের করে।

এটি কেবল ভার্চুয়াল ফাংশনগুলিতেই প্রযোজ্য না, তবে টাইপডেফের নাম, স্থির / নন-ভার্চুয়াল সদস্য এবং অন্য যে কোনও কিছুতেও প্রযোজ্য। আমি এটি মেটা প্রোগ্রামগুলিতে ওভাররাইটযোগ্য বৈশিষ্ট্যগুলি প্রয়োগ করতে ব্যবহার করেছি।


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