c++ - লাম্বদার মধ্যেই কীভাবে একটি সি++ ল্যাম্বডা ফাংশনের ঠিকানা পাবেন?




c++11 lambda (4)

আমি কীভাবে নিজের মধ্যে ল্যাম্বডা ফাংশনের ঠিকানা পেতে পারি তা জানার চেষ্টা করছি। এখানে একটি নমুনা কোড রয়েছে:

[]() {
    std::cout << "Address of this lambda function is => " << ????
}();

আমি জানি যে আমি ল্যাম্বডাকে একটি ভেরিয়েবলে ক্যাপচার করতে পারি এবং ঠিকানাটি মুদ্রণ করতে পারি, তবে এই বেনাম ফাংশনটি সম্পাদন করার সময় আমি এটি জায়গায় করতে চাই।

এটি করার সহজ উপায় আছে?


এখানে একটি প্রতিশ্রুতি সংস্করণ পদ্ধতির:

#include <future>
#include <cstdio>

int main() {
    std::promise<void *> p;

    auto f = [ready_future = p.get_future()]() mutable {
             printf("%p\n", ready_future.get());
        };

    p.set_value(&f);

    f();
}

এটি সমাধানের একটি উপায় হ'ল লিখিত ফান্টার ক্লাসের সাথে ল্যাম্বডা প্রতিস্থাপন করা। এটি ল্যাম্বডা মূলত হুডের নীচে রয়েছে।

তারপরে আপনি এর মাধ্যমে ঠিকানাটি পেতে পারেন, এমনকি কোনও ভেরিয়েবলের জন্য ফান্টরকে কখনও না নিযুক্ত করে:

#include <iostream>

class Functor
{
public:
    void operator()() {
        std::cout << "Address of this functor is => " << this;
    }
};

int main()
{
    Functor()();
    return 0;
}

আউটপুট:

Address of this functor is => 0x7ffd4cd3a4df

এটির সুবিধাটি এটি 100% পোর্টেবল, এবং সম্পর্কে যুক্তিযুক্ত এবং বোঝার পক্ষে অত্যন্ত সহজ।


এটি সরাসরি সম্ভব নয়।

তবে লাম্বদা ক্যাপচারগুলি ক্লাস এবং কোনও বস্তুর ঠিকানা তার প্রথম সদস্যের ঠিকানার সাথে মিলে যায়। অতএব, আপনি যদি প্রথম ক্যাপচার হিসাবে মান হিসাবে একটি বস্তু ক্যাপচার করেন, তবে প্রথম ক্যাপচারের ঠিকানা ল্যাম্বডা অবজেক্টের ঠিকানার সাথে মিলে যায়:

int main() {
    int i = 0;
    auto f = [i]() { printf("%p\n", &i); };
    f();
    printf("%p\n", &f);
}

আউটপুট:

0x7ffe8b80d820
0x7ffe8b80d820

বিকল্পভাবে, আপনি একটি ডেকরেটর ডিজাইনের প্যাটার্ন ল্যাম্বদা তৈরি করতে পারেন যা ল্যাম্বদা ক্যাপচারের রেফারেন্সটিকে তার কল অপারেটরে পাস করে:

template<class F>
auto decorate(F f) {
    return [f](auto&&... args) mutable {
        f(f, std::forward<decltype(args)>(args)...);
    };
}

int main() {
    auto f = decorate([](auto& that) { printf("%p\n", &that); });
    f();
}

ল্যাম্বডায় কোনও ল্যাম্বডা অবজেক্টের ঠিকানা সরাসরি পাওয়ার কোনও উপায় নেই।

এখন, এটি হিসাবে এটি প্রায়শই দরকারী। সর্বাধিক সাধারণ ব্যবহারটি পুনরাবৃত্তি করার জন্য।

y_combinator এমন ভাষা থেকে আসে যেখানে আপনি নিজের সংজ্ঞায়িত না হওয়া অবধি নিজের সম্পর্কে কথা বলতে পারবেন না। এটি সি ++ তে খুব সহজেই প্রয়োগ করা যেতে পারে:

template<class F>
struct y_combinator {
  F f;
  template<class...Args>
  decltype(auto) operator()(Args&&...args) const {
    return f( f, std::forward<Args>(args)... );
  }
  template<class...Args>
  decltype(auto) operator()(Args&&...args) {
    return f( f, std::forward<Args>(args)... );
  }
};

এখন আপনি এটি করতে পারেন:

y_combinator{ [](auto& self) {
  std::cout<<"Address of this lambda function is => "<< &self;
} }();

এর বিভিন্নতা অন্তর্ভুক্ত করতে পারে:

template<class F>
struct y_combinator {
  F f;
  template<class...Args>
  decltype(auto) operator()(Args&&...args) const {
    return f( *this, std::forward<Args>(args)... );
  }
  template<class...Args>
  decltype(auto) operator()(Args&&...args) {
    return f( *this, std::forward<Args>(args)... );
  }
};

যেখানে self স্বতঃকে প্রথম যুক্তি হিসাবে স্বীকার না করে কল করা যেতে পারে।

দ্বিতীয়টি বিশ্বাস করে সত্যিকারের y কম্বিনেটর (ওরফে ফিক্সড পয়েন্ট কম্বিনেটর) আমি বিশ্বাস করি। আপনি যা চান তা নির্ভর করে 'ল্যাম্বদার ঠিকানা' দ্বারা আপনি কী বোঝাতে চান তার উপর depends





c++17