ল্যাম্বডা ম্যাক্রো কীভাবে ল্যাম্বডা তৈরি করে?


20

আমি কোডটি এই টুকরোটি গিটহাবের মধ্যে পেয়েছি কিন্তু এটি বেশ বুঝতে পারি নি:

#define lambda(ret_type, _body) ({ ret_type _ _body _; })

তারপর:

int (*max)(int, int) = lambda(int,
                             (int x, int y) {
                                 return x > y ? x : y;
                             });

int max_value = max(1, 2);
// max_value is 2

আন্ডারস্কোরগুলি ভিতরে কী করছে #defineএবং এটি কীভাবে কোনও ফাংশন পয়েন্টারটি ফিরিয়ে দেয়?


7
আপনি কি ম্যাক্রোটি প্রসারিত করার চেষ্টা করেছেন (উদাহরণস্বরূপ gcc -E) এটি কী করে তা দেখার জন্য?
বেহুদা

5
অনুগ্রহ করে সম্প্রসারণ Godbolt.org/z/C5TLWj দেখুন ফলাফলটি যদিও বুঝতে সহজ হয় না
ইউজিন শ।

2
আমি ধরে নিয়েছি যে আপনি এই কোডটি পেয়েছেন সেই জায়গার চারপাশের মন্তব্যের ভিত্তিতে আপনি জানেন তবে এটি নেস্টেড ফাংশনগুলির জন্য জিসিসি এক্সটেনশনের উপর নির্ভর করে।
থমাস জাগার

4
@EugeneSh। এটি জিসিসির নেস্টেড ফাংশনগুলি ব্যবহার করে একটি ফাংশন পয়েন্টার শুরু করছে। মূল কোডটি এখান থেকে । এই প্রকল্পটি আজ হ্যাকার নিউজে ভাগ করা হয়েছিল।
থমাস জাগার

4
@EugeneSh। এটি দুটি জিসিসি এক্সটেনশনের সংমিশ্রণ: নেস্টেড ফাংশন এবং এক্সপ্রেশনগুলিতে যৌগিক বিবৃতি । নেস্টেড ফাংশনটি যৌগিক বিবরণের ভিতরে উপস্থিত হয়।
ইন্টারজয়

উত্তর:


10

এই ম্যাক্রো ব্যবহার করে,

int (*max)(int, int) = lambda(int,
                             (int x, int y) {
                                 return x > y ? x : y;
                             });

এতে প্রসারিত:

int (*max)(int, int) = ({
    int _ (int x, int y) { return x > y ? x : y; }
    _;
});

কোঁকড়া ধনুর্বন্ধনীগুলিতে, এটি পছন্দসই ক্রিয়াকলাপ সম্পাদন করে এমন একটি ক্রিয়াকলাপ তৈরি করতে জিসিসির নেস্টেড ফাংশন ব্যবহার করে। অভ্যন্তরীণ সুযোগের মধ্যে এটির নাম রয়েছে _

তারপরে, ইন্টারজয় দ্বারা উল্লিখিত হিসাবে, জিসিসির বিবৃতি এক্সপ্রেশনগুলি ব্যবহৃত হয়। কার্যকরভাবে, ফাংশনটি _পয়েন্টারটিতে নির্ধারিত হয় max

যদি এই জাতীয় ম্যাক্রো ব্যবহার না করা হয় তবে এটি অন্যভাবে লেখা যেতে পারে এবং হিসাবে ব্যবহার করা যেতে পারে:

int val1 = 4;
int val2 = -30;

int perform_operation(int (*op)(int, int)) {
    int new_val = op(val1, val2);
    val1 = val2;
    val2 = new_val;
    return new_val;
}

int enclosing_function (void) {
    // Create max "lambda"
    int (*max)(int, int);
    {
        // Curly braces limit the scope of _
        int _ (int x, int y) { return x > y ? x : y; }
        max = _;
    }

    return perform_operation(max);
}

এই কোড উদাহরণে তিনটি পদ্ধতির তুলনা করা যেতে পারে ।


ম্যাক্রো কিছুই করে না কারণ এটি
জিসিসিতে

@ পি__জে__ এটি আদর্শ সংকলন করে / টি 5 এফএলএক্সবি
ইউজিন শ।

@ পি__জে__ আমি আমার উত্তরের শেষে একটি উদাহরণ যুক্ত করেছি যা দেখায় যে এই ম্যাক্রোটি ব্যবহৃত হচ্ছে।
থমাস জাগার

এর max(4, -30);বদলে আপনি কেন পারবেন না apply_binary_op(max, 4, -30);?
এসএস আন

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

7

একে স্টেটমেন্ট এক্সপ্রেশন বলা হয় এবং একটি "ল্যাম্বডা" (বা নেস্টেড ফাংশন ) তৈরি করে এবং এতে একটি পয়েন্টার ফিরিয়ে দেয়। এটি জিএনইউ সি-নির্দিষ্ট।

ম্যাক্রো এতে প্রসারিত:

int (*max)(int, int) = ({ int _ (int x, int y) { return x > y ? x : y; } _; })

_শেষে একটি মত হল return

আন্ডারস্কোরটি আসলে তৈরি করা এবং "ফিরে আসা" ফাংশনের নাম। এটি ব্যবহৃত হয় কারণ এটি একটি অস্বাভাবিকভাবে ব্যবহৃত সনাক্তকারী (সঠিক কারণে; _সম্ভবত কমপক্ষে বর্ণনামূলক শনাক্তকারী সম্ভবত)।

স্টেটমেন্ট এক্সপ্রেশনটি ব্যবহার করার কারণটি তাই বিবৃতি প্রকাশের _সুযোগ ছাড়ার পরে সংজ্ঞায়িত হবে না।

সুতরাং, ম্যাক্রো মাধ্যমে যেতে:

#define lambda(ret_type, _body) ({ ret_type _ _body _; })

ret_type"ল্যাম্বদা" এর রিটার্ন টাইপ। _এটির ভিতরে ব্যবহৃত ফাংশনটির নাম এটি একটি অস্বাভাবিক সনাক্তকারী নাম। _bodyফাংশনের আর্গুমেন্ট এবং বডি নিয়ে গঠিত। পেছনের _দিকটি "ল্যাম্বদা" "ফিরিয়ে দেয়"।

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

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

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