গ্লোবাল ল্যাম্বডাস ব্যবহার না করার কোনও কারণ?


89

আমাদের একটি ফাংশন ছিল যা একটি নন-ক্যাপচারিং ল্যাম্বদা নিজের মধ্যে অভ্যন্তরীণভাবে ব্যবহার করেছিল, যেমন:

void foo() {
  auto bar = [](int a, int b){ return a + b; }

  // code using bar(x,y) a bunch of times
}

এখন ল্যাম্বডা দ্বারা কার্যকর করা কার্যকারিতা অন্য কোথাও প্রয়োজনীয় হয়ে উঠেছে, তাই আমি ল্যাম্বডাকে foo()বিশ্বব্যাপী / নেমস্পেসের বাইরে নিয়ে যেতে চলেছি । আমি হয় এটিকে একটি ল্যাম্বডা হিসাবে রেখে একটি অনুলিপি-অনুলিপি বিকল্প হিসাবে তৈরি করতে পারি বা এটি একটি উপযুক্ত ফাংশনে পরিবর্তন করতে পারি:

auto bar = [](int a, int b){ return a + b; } // option 1
int bar(int a, int b){ return a + b; } // option 2

void foo() {
  // code using bar(x,y) a bunch of times
}

এটি একটি যথাযথ কার্যক্রমে পরিবর্তন করা তুচ্ছ, তবে এটি আমাকে লম্বা হিসাবে ছেড়ে না যাওয়ার কোনও কারণ আছে কিনা তা অবাক করে দিয়েছিল ? "নিয়মিত" গ্লোবাল ফাংশনগুলির পরিবর্তে সব জায়গায় কেবল ল্যাম্বডাস ব্যবহার না করার কোনও কারণ আছে কি?


আমি ধরে নিই যে ল্যাম্বডাস সাবধানতার সাথে ব্যবহার না করা হলে অযৌক্তিক চলকগুলি ক্যাপচার করা অনেক ত্রুটি ঘটাতে পারে
macroland

উত্তর:


61

গ্লোবাল ল্যাম্বডাস ব্যবহার না করার একটি অত্যন্ত গুরুত্বপূর্ণ কারণ রয়েছে: কারণ এটি স্বাভাবিক নয়।

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

একটি গ্লোবাল ল্যাম্বদা পুরোপুরি একটি আলাদা জন্তু। এটির নিয়মিত ফাংশন থেকে আলাদা আচরণ রয়েছে behavior লাম্বডাস হ'ল বস্তু, যখন ফাংশনগুলি হয় না। তাদের একটি প্রকার রয়েছে, তবে সেই ধরণটি তাদের ফাংশনের ধরণের থেকে পৃথক। এবং তাই এগিয়ে।

সুতরাং এখন, আপনি অন্যান্য প্রোগ্রামারদের সাথে যোগাযোগের বারটি উত্থাপন করেছেন। একটি সি ++ প্রোগ্রামার ল্যাম্বডাস বুঝতে হবে যদি তারা বুঝতে পারে যে এই ফাংশনটি কী করছে। এবং হ্যাঁ, এটি 2019, সুতরাং একটি শালীন সি ++ প্রোগ্রামারের একটি ল্যাম্বডা দেখতে কেমন তা ধারণা করা উচিত। তবে এটি এখনও একটি উচ্চতর বার।

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

উপন্যাসগুলি যেখানে উপযুক্ত সেখানে প্রত্যাশিত সমাধানগুলি পছন্দ করুন। আপনার পয়েন্টটি জুড়ে পাওয়ার সবচেয়ে কম জটিল পদ্ধতিটি ব্যবহার করুন।


9
"সি এর দিনগুলি থেকে" তার আগে আমার পথ
লাইটনেস রেস অরবিট

4
@ লাইটনেসেস: আমার মূল বক্তব্যটি প্রকাশ করা ছিল যে সি ++ এর ফাংশন সিনট্যাক্স সি এর পর থেকে রয়েছে, তাই অনেক লোকই জানেন এটি পরীক্ষা করে inspection
নিকল বোলাস

2
প্রথম বাক্যটি বাদে এই উত্তরের সাথে একমত হন। "এটি সাধারণ নয়" এটি একটি অস্পষ্ট এবং অবাস্তব বক্তব্য। সম্ভবত আপনি "এটি অস্বাভাবিক এবং বিভ্রান্তিকর" অর্থে বোঝাতে চেয়েছিলেন?
einpoklum

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

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

53

আমি কয়েকটি কারণ সম্পর্কে ভাবতে পারি যে আপনি নিয়মিত ফাংশনগুলির জন্য ড্রপ-ইন প্রতিস্থাপন হিসাবে গ্লোবাল ল্যাম্বডাস এড়াতে চান:

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

"রাষ্ট্রীয় ফান্টেক্টর (ক্লাস) প্রতিস্থাপনের জন্য কেন আমি ল্যাম্বডাস ব্যবহার করব না?"

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

একটি ল্যাম্বডায় অন্তর্নিহিত "এই" পয়েন্টারটিও রয়েছে (এমনকী একটি নন-ক্যাপচারিংও) যা ফাংশনটিকে কল করে ল্যাম্বদা বনাম কল করার সময় একটি অতিরিক্ত প্যারামিটারের ফলাফল করে।
1201 প্রোগ্রাম অ্যালার্ম

@ 1201 প্রোগ্রাম অ্যালার্ম: এটি একটি ভাল পয়েন্ট; ল্যাম্বডায় ফাংশন পয়েন্টার পাওয়া অনেক বেশি কঠিন হতে পারে (যদিও নন-ক্যাপচারিং ল্যাম্বডাস নিয়মিত ফাংশন পয়েন্টারগুলিতে ক্ষয় করতে পারে)
AndyG

3
ফ্লিপ-সাইডে, যদি সরাসরি কল করার পরিবর্তে এটি কোথাও পাস করা হয় তবে কোনও ফাংশনের পরিবর্তে ল্যাম্বডা রাখলে ইনলাইনিংকে উত্সাহ দেওয়া হয়। স্বাভাবিকভাবেই, কেউ তার জন্য ফাংশন-পয়েন্টারটি প্যাক করতে পারে std::integral_constant...
ডেডুয়ালিকেটর

@ উত্সাহক: " একটি ফাংশনের পরিবর্তে ল্যাম্বডা থাকা ইনলাইনিংকে উত্সাহ দেয় " কেবল পরিষ্কার, এটি কেবল তখনই প্রযোজ্য যদি "কোথাও" কোনও টেমপ্লেট থাকে যা কোনও ফাংশন পয়েন্টারকে না বলে ফাংশনটিকে একটি স্বেচ্ছাচারী কলযোগ্য প্রকার হিসাবে ডাকে।
নিকল বোলাস

2
@ অ্যান্ডিজি আপনি বিধি-বিধানটি ভুলে যাচ্ছেন: এমন প্রোগ্রামগুলি যা ল্যাম্বডা আকারের জন্য অনুরোধ করে না (কারণ… কেন ?!), বা এটির জন্য কোনও পয়েন্টার তৈরি করে না, প্রয়োজন নেই (এবং সাধারণত না) এর জন্য জায়গা বরাদ্দ করুন।
কনরাড রুডল্ফ

9

জিজ্ঞাসা করার পরে, আমি এটি না করার কারণ ভেবেছিলাম: যেহেতু এগুলি পরিবর্তনশীল, তাই এগুলি স্ট্যাটিক ইনিশিয়ালাইজেশন অর্ডার ফায়াসকো ( https://isocpp.org/wiki/faq/ctors#static-init-order ) প্রবণ হয় , যা পারে লাইন নীচে বাগ কারণ।


আপনি তাদের ল্যাম্বডাস তৈরি করতে পারেন constexpr... আসল বিষয়টি হ'ল: কেবল একটি ফাংশন ব্যবহার করুন।
einpoklum

8

"নিয়মিত" গ্লোবাল ফাংশনগুলির পরিবর্তে সব জায়গায় কেবল ল্যাম্বডাস ব্যবহার না করার কোনও কারণ আছে কি?

একটি নির্দিষ্ট স্তরের জটিলতার সমস্যার জন্য কমপক্ষে একই জটিলতার সমাধান প্রয়োজন। তবে একই সমস্যাটির জন্য যদি কোনও জটিল জটিল সমাধান হয়, তবে আরও জটিল সমস্যাটি ব্যবহার করার পক্ষে সত্যই কোনও যৌক্তিকতা নেই। আপনার প্রয়োজন নেই এমন জটিলতার পরিচয় দেবেন কেন?

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


6

লাম্বদাস বেনামে ফাংশন

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


1
এটি পরিভাষা থেকে একটি যুক্তি বলে মনে হয়, অর্থাৎ। বিভ্রান্তিকর নামকরণ এবং অর্থ। এটি নির্ধারণ করে সহজেই খণ্ডন করা যায় যে নামযুক্ত ল্যাম্বদা আর বেনামে (দুহ) নয়। এখানে সমস্যাটি ল্যাম্বডা কীভাবে ব্যবহৃত হয় তা নয়, এটি "বেনামে ফাংশন" একটি ভুল নাম, এবং যখন ল্যাম্বদা নামের সাথে আবদ্ধ থাকে তখন আর সঠিক হয় না।
কনরাড রুডল্ফ

@ কনরাড রুডল্ফ: এটি কেবল পরিভাষা নয়, এ কারণেই এগুলি প্রথম স্থানে তৈরি করা হয়েছিল। কমপক্ষে historতিহাসিকভাবে, ল্যাম্বডাস অজ্ঞাতনামা ফাংশন এবং সে কারণেই এটি নামকরণ করা বিভ্রান্তিকর, বিশেষত যখন পরিবর্তে ফাংশনগুলি প্রত্যাশিত হয়।
এরিক ডুমিনিল

1
নাহ। ল্যাম্বডাসের নাম নিয়মিত করা হয় (কেবলমাত্র স্থানীয়ভাবে), এ সম্পর্কে বিভ্রান্তিকর কিছুই নেই।
কনরাড রুডল্ফ

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

5

যদি লাম্বদা না রেখে কিছু কারণ থাকে? "নিয়মিত" গ্লোবাল ফাংশনগুলির পরিবর্তে সব জায়গায় কেবল ল্যাম্বডাস ব্যবহার না করার কোনও কারণ আছে কি?

আমরা গ্লোবাল ফান্টারের পরিবর্তে ফাংশন ব্যবহার করতাম, সুতরাং এটি সামঞ্জস্যতা এবং অন্তত বিস্ময়ের মূলনীতিটি ভেঙে দেয় ।

প্রধান পার্থক্যগুলি হ'ল:

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