আমি কেন লাম্বদাতে এই বাই-রেফারেন্স ('& এটি') ক্যাপচার করতে পারি না?


91

আমি thisল্যাম্বডায় ক্যাপচার (অবজেক্টের বৈশিষ্ট্যগুলি সংশোধন করার) সঠিক উপায়টি বুঝতে পারি :

auto f = [this] () { /* ... */ };

তবে আমি দেখেছি নিম্নলিখিত অদ্ভুততা সম্পর্কে কৌতূহলী:

class C {
    public:
        void foo() {
            // auto f = [] () { // this not captured
            auto f = [&] () { // why does this work?
            // auto f = [&this] () { // Expected ',' before 'this'
            // auto f = [this] () { // works as expected
                x = 5;
            };
            f();
        }

    private:
        int x;
};

আমি যে অদ্ভুততা দ্বারা বিভ্রান্ত হয়েছি (এবং তার উত্তর দিতে চাই) তা কেন নিম্নলিখিত কাজ করে:

auto f = [&] () { /* ... */ }; // capture everything by reference

এবং কেন আমি স্পষ্ট thisকরে রেফারেন্স দ্বারা ক্যাপচার করতে পারি না :

auto f = [&this] () { /* ... */ }; // a compiler error as seen above.

6
আপনি চান কেন ? যে বিষয়গুলির জন্য কোনও পয়েন্টারের রেফারেন্সটি বোধগম্যভাবে কার্যকর হতে thisপারে: পরিবর্তিত হতে পারে না, এটি একটি রেফারেন্স দ্রুততর করার পক্ষে এত বড় নয় ... এবং যাইহোক , এটি আসলে বিদ্যমান নয় , তাই এর রয়েছে কোনও বাস্তব জীবনকাল নয়, এর অর্থ কোনও সংজ্ঞা সংজ্ঞা অনুসারে ঝুঁকবে। thisএকটি মূল্য আছে, একটি মূল্য নয়।
আন্ডারস্কোর_১

উত্তর:


111

কারণ [&this]কাজ করে না কারণ এটি একটি সিনট্যাক্স ত্রুটি। এর প্রতিটি কমা-বিভক্ত পরামিতি lambda-introducerহ'ল capture:

capture:
    identifier
    & identifier
    this

আপনি দেখতে পাচ্ছেন যে &thisসিনট্যাক্টিকভাবে অনুমোদিত নয়। এটি অনুমোদিত না হওয়ার কারণ হ'ল আপনি কখনই thisরেফারেন্স দ্বারা ক্যাপচার করতে চান না কারণ এটি একটি ছোট কনস্ট পয়েন্টার। আপনি কেবলমাত্র এটির দ্বারা মানটি পাস করতে চাইবেন - সুতরাং ভাষাটি কেবল thisরেফারেন্স দ্বারা ক্যাপচার সমর্থন করে না support

thisস্পষ্টত ক্যাপচার আপনি [this]হিসাবে হিসাবে ব্যবহার করতে পারেন lambda-introducer

প্রথমটি যা captureহতে পারে capture-defaultতা হ'ল:

capture-default:
    &
    =

এর অর্থ হ'ল আমি যা যা ব্যবহার করি তা যথাক্রমে রেফারেন্স ( &) বা মান দ্বারা =) ব্যবহার করে - তবে এর চিকিত্সা thisবিশেষ - উভয় ক্ষেত্রেই এটি পূর্বের কারণে (এমনকি একটি ডিফল্ট ক্যাপচারের সাথেও &বোঝায় যা মূলত অর্থ হিসাবে ধরা হয়) রেফারেন্স দ্বারা ক্যাপচার)।

5.1.2.7/8:

নাম অনুসন্ধানের জন্য (৩.৪), this(9.3.2) এর ধরণ এবং মান নির্ধারণ এবং অ স্থিত শ্রেণীর সদস্যদের ক্লাস সদস্য অ্যাক্সেস এক্সপ্রেশন (*this)(9.3.1) ব্যবহার করে যৌগিক বিবৃতি [অফ ল্যাম্বদা] ল্যাম্বডা-অভিব্যক্তির প্রসঙ্গে বিবেচনা করা হয়।

সুতরাং ল্যাম্বদা সদস্যের নাম ব্যবহার করার সময় এটি ঘেরানো সদস্য ফাংশনের অংশ হিসাবে কাজ করে (যেমন উদাহরণ হিসাবে নাম ব্যবহার করে x), সুতরাং এটি thisকোনও সদস্য ফাংশনের মতোই "অন্তর্নিহিত ব্যবহারগুলি" তৈরি করবে ।

যদি কোনও ল্যাম্বদা-ক্যাপচারের সাথে ক্যাপচার-ডিফল্ট অন্তর্ভুক্ত থাকে &তবে ল্যাম্বডা-ক্যাপচারের শনাক্তকারীরা এর আগে চলবে না &। যদি কোনও ল্যাম্বদা-ক্যাপচারের সাথে ক্যাপচার-ডিফল্ট অন্তর্ভুক্ত =থাকে তবে ল্যাম্বডা-ক্যাপচারটি থাকা উচিত নয় thisএবং এতে থাকা প্রতিটি শনাক্তকারী এর আগে থাকা উচিত &। একটি সনাক্তকারী বা thisলাম্বদা-ক্যাপচারে একাধিকবার উপস্থিত হবে না।

তাই আপনি ব্যবহার করতে পারেন [this], [&], [=]বা [&,this]হিসেবে lambda-introducerক্যাপচার thisমান পয়েন্টার।

যাইহোক [&this]এবং [=, this]গঠনমূলক হয়। গত কেস জিসিসি সালে forgivingly জন্য সতর্ক [=,this]যে explicit by-copy capture of ‘this’ redundant with by-copy capture defaultবদলে ত্রুটি।


4
@ কনরাড রুডল্ফ: আপনি যদি মূল্য দিয়ে কিছু জিনিস এবং রেফারেন্সের সাহায্যে অন্য কিছু ধরতে চান তবে কী হবে? বা আপনি যা ক্যাপচার করেছেন তার সাথে খুব স্পষ্ট হতে চান?
Xoo

4
@ কনরাড রুডল্ফ: এটি একটি সুরক্ষা বৈশিষ্ট্য। আপনি দুর্ঘটনাক্রমে এমন নামগুলি ক্যাপচার করতে পারেন যা আপনি করতে চান না।
অ্যান্ড্রু তোমাজস

8
@ কনরাডরুডল্ফ: ব্লক-স্তরের কনস্ট্রাক্টসগুলি কোনও নতুন অদৃশ্য বেনামি প্রকারের জন্য তারা যে বস্তুগুলি ব্যবহার করে সেগুলিতে যাদুকরীভাবে কোনও পয়েন্টারকে অনুলিপি করে না যা কেবল আবদ্ধকরণের মধ্যে অবজেক্টের নাম ব্যবহার করে। ল্যাম্বদা ক্যাপচারিং একটি বিপজ্জনক ব্যবসায়ের অনেক বেশি।
অ্যান্ড্রু তোমাজোস

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

4
@ রুসলান: না, thisএকটি কীওয়ার্ড, thisশনাক্তকারী নয়।
অ্যান্ড্রু তোমাজস

6

কারণ &thisক্যাপচার তালিকায় স্ট্যান্ডার্ডের নেই :

N4713 8.4.5.2 ক্যাপচার:

lambda-capture:
    capture-default
    capture-list
    capture-default, capture-list

capture-default:
    &
    =
capture-list:
    capture...opt
    capture-list, capture...opt
capture:
    simple-capture
    init-capture
simple-capture:
    identifier
    &identifier
    this
    * this
init-capture:
    identifier initializer
    &identifier initializer
  1. ল্যাম্বদা ক্যাপচারের উদ্দেশ্যে, একটি অভিব্যক্তিটি স্থানীয় সত্ত্বাকে নিম্নরূপ উল্লেখ করে:

    7.3 এ অভিব্যক্তিটি সম্ভবত এটি * উল্লেখ করে।

সুতরাং, মানক গ্যারান্টি দেয় thisএবং *thisবৈধ এবং &thisঅবৈধ। এছাড়াও, আটক thisআটক মানে *this(যা একটি lvalue, বস্তুর নিজেই) রেফারেন্স দ্বারা , বরং ধরে thisপয়েন্টার মান !


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