লাম্বদা ক্লোজার লভ্যালুগুলি যথাযথ রেফারেন্স পরামিতি হিসাবে পাস করা যেতে পারে


18

আমি দেখেছি যে lvalueল্যাম্বদা ক্লোজারগুলি সর্বদা rvalueফাংশন পরামিতি হিসাবে পাস করা যায় ।

নিম্নলিখিত সহজ বিক্ষোভ দেখুন।

#include <iostream>
#include <functional>

using namespace std;

void foo(std::function<void()>&& t)
{
}

int main()
{
    // Case 1: passing a `lvalue` closure
    auto fn1 = []{};
    foo(fn1);                          // works

    // Case 2: passing a `lvalue` function object
    std::function<void()> fn2 = []{};
    foo(fn2);                          // compile error

    return 0;
}

কেস 2 হ'ল মানক আচরণ (আমি কেবল std::functionপ্রদর্শনের উদ্দেশ্যে ব্যবহার করেছি, তবে অন্য কোনও ধরণের আচরণ একই রকম হবে)।

কেস 1 কেন এবং কেন কাজ করে? fn1ফাংশন ফিরে আসার পরে বন্ধের অবস্থা কী ?


5
আমি অনুমান করি যে এটি fn1অন্তর্নিহিতভাবে একটি std::functionইন-এ রূপান্তরিত হয়েছে foo(fn1)। সেই অস্থায়ী ফাংশনটি তখন একটি মূল্যবান।
eike

@ রিচার্ড ক্রিটটেন আমি সত্যই নিশ্চিত নই, তাই আমি কোনও উত্তর পোস্ট করিনি। আমার মনে হয় এখন আর একজনের দরকার নেই।
eike

1
@ eike এনপি আমি প্রায়শই একইরকম অনুভব করি এবং অনেক উত্তর সরিয়ে রাখি।
রিচার্ড ক্রিটেন

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

1
আপনার লিঙ্ক করা প্রশ্নের শিরোনামটি কিছুটা বিভ্রান্তিকর। std::functionলাম্বদা ক্লোজারকে স্বীকার করে এমন একটি স্পষ্টত নির্মাতা নির্মাণকারী রয়েছে, সুতরাং অন্তর্নিহিত রূপান্তর রয়েছে। তবে সংযুক্ত প্রশ্নের পরিস্থিতিতে std::functionল্যাম্বদা টাইপ থেকে টেমপ্লেট ইনস্ট্যান্টেশন অনুমান করা যায় না। (উদাহরণস্বরূপ এটির অ- std::function<void()>[](){return 5;}
শূন্য

উত্তর:


8

কেস 1 কেন এবং কেন কাজ করে?

Invoking fooএকটি দৃষ্টান্ত প্রয়োজন std::function<void()>একটি যে শুশ্রূষা rvalue রেফারেন্স । স্বাক্ষরের সাথে সামঞ্জস্যপূর্ণ যে std::function<void()>কোনও কলযোগ্য বস্তু থেকে তৈরি করা যেতে পারে void()

প্রথমত, একটি অস্থায়ী std::function<void()>বস্তু থেকে নির্মিত হয় []{}। ব্যবহৃত কনস্ট্রাক্টরটি এখানে # 5 , যা ক্লোজারটি অনুলিপি করে std::function:

template< class F >
function( F f );

সাথে লক্ষ্যটি শুরু করে std::move(f)। যদি fফাংশন করার জন্য নাল পয়েন্টার হয় বা সদস্যের কাছে নাল পয়েন্টার হয়, *thisকল করার পরে খালি হবে।

তারপরে, অস্থায়ী functionউদাহরণটি মূল্যের রেফারেন্সে আবদ্ধ।


ফাংশন ফিরে আসার পরে fn1 বন্ধের অবস্থা কী?

আগের মতোই, কারণ এটি একটি std::functionদৃষ্টান্তে অনুলিপি করা হয়েছিল । আসল বন্ধটি প্রভাবিত নয়।


8

একটি ল্যাম্বদা একটি হয় না std::function। রেফারেন্স সরাসরি আবদ্ধ হয় না ।

কেস 1 কাজ করে কারণ ল্যাম্বডাস std::functionএস তে রূপান্তরিত । এর অর্থ হল একটি অস্থায়ী অনুলিপিstd::function দ্বারা বস্তুগত হয় । অস্থায়ী বলেছিল একটি মূল্যের রেফারেন্সের সাথে আবদ্ধ হতে সক্ষম, এবং সুতরাং যুক্তিটি প্যারামিটারের সাথে মেলে। fn1

এবং অনুলিপি এছাড়াও কেন fn1সম্পূর্ণভাবে কিছু ঘটবে দ্বারা প্রভাবিত হয় foo


5

ফাংশন ফিরে আসার পরে fn1 বন্ধের অবস্থা কী?

fn1 রাষ্ট্রহীন, যেহেতু এটি কিছুই ধারণ করে না।

কেস 1 কেন এবং কেন কাজ করে?

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

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