সি ++ 11 এ স্টাডি :: ফাংশনটি খালি কিনা তা কীভাবে সঠিকভাবে পরীক্ষা করবেন?


99

আমি ভাবছিলাম যে কীভাবে std::functionখালি আছে তা সঠিকভাবে চেক করব । এই উদাহরণ বিবেচনা করুন:

class Test {
    std::function<void(int a)> eventFunc;

    void registerEvent(std::function<void(int a)> e) {
        eventFunc = e;
    }

    void doSomething() {
        ...
        eventFunc(42);
    }
};

এই কোডটি এমএসভিসিতে ঠিক জরিমানা সংকলন করেছে তবে আমি কোডটি doSomething()শুরু না eventFuncকরে কল করলে স্পষ্টতই ক্র্যাশ হয়। এটা প্রত্যাশিত কিন্তু আমি ভাবছিলাম এর মান কী eventFunc? ডিবাগার বলেছেন 'empty'। সুতরাং আমি স্থির করেছি যে সহজ যদি বিবৃতি ব্যবহার করে:

   void doSomething() {
        ...
        if (eventFunc) {
            eventFunc(42);
        }
   }

এটি কাজ করে তবে আমি এখনও ভাবছি যে অ-আরম্ভ করার মান কী std::function? আমি লিখতে চাই if (eventFunc != nullptr)তবে std::functionপয়েন্টার নয় (স্পষ্টতই)।

শুদ্ধ কেন কাজ করে? এর পিছনে যাদু কী? এবং, এটি কীভাবে পরীক্ষা করা যায় এটি সঠিক উপায়?


8
নোট যে eventFuncল্যাম্বদা নয়; এটি একটি std::function। আপনি লম্বাডসগুলিতে সংরক্ষণ করতে পারেন std::functionতবে তারা একই জিনিস নয়।
টেম্পলেটটিফাইফ

4
আপনি ঠিক বলেছেন, বিভ্রান্তি এড়াতে আমি শিরোনাম পরিবর্তন করেছি। ধন্যবাদ
নাইটএলফিক

উত্তর:


107

আপনি খালি ল্যাম্বদা পরীক্ষা করছেন না, তবে এতে কল করার std::functionলক্ষ্য রয়েছে কিনা তা। চেকটি সুস্পষ্টভাবে সংজ্ঞায়িত হয়েছে এবং এটি কাজ করে std::function::operator boolযার কারণে boolবুলিয়ান মানগুলি প্রয়োজনীয় (যেমন একটি ifবিবৃতিতে শর্তসাপেক্ষ অভিব্যক্তি ) প্রাসঙ্গিকগুলিতে অন্তর্নিহিত রূপান্তর করতে দেয় ।

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


আপনি চাইলে লিখতেও if(eventFunc != nullptr)পারেন, এটি আপনার প্রশ্নের কোডের সমতুল্য। std::function সংজ্ঞায়িত operator== এবং operator!=একটি সঙ্গে তুলনা জন্য overloads nullptr_t


4
না == nullptr, একই জিনিস করে যদিও? দেখে মনে হচ্ছে সেখানে একটি জমিদার হতে অনুমিত এর ==যে একটি "খালি" ঘটায় অপারেটর std::functionতুলনা trueবিরুদ্ধে nullptr: cplusplus.com/reference/functional/function/operators
কাইলি স্ট্র্যান্ড

4
@ কাইলস্ট্র্যান্ড হ্যাঁ, তুলনা করা nullptrখুব বেশি কাজ করবে, উপরের প্রশ্নটির if(eventFunc != nullptr)সমান if(eventFunc)
প্রিটোরিয়ান

4
প্রযুক্তিগতভাবে, std::function::operator boolঅন্তর্নিহিত রূপান্তরটির অনুমতি দেয় না bool। এটি explicitসর্বোপরি চিহ্নিত করা হয়েছে, তবে মানটি নির্দিষ্ট ভাষা নির্মানের জন্য ব্যতিক্রম করে যা বুলিয়ান এক্সপ্রেশনগুলির প্রত্যাশা করে, এটিকে "প্রাসঙ্গিকভাবে বুলে রূপান্তরিত" বলে অভিহিত করে। আপনি স্ট্যান্ডার্ডিজ সম্পর্কিত স্নিপেট এবং একটি ব্যাখ্যা এখানে পেতে পারেন: chris-sharpe.blogspot.com/2013/07/…
খ্রিস্ট

@ বিক্রিস্ট হ্যাঁ, আমি জানি যে বুলিয়ান রূপান্তরকারী অপারেটর explicit, সেই কারণেই আমি সতর্ক ছিলাম যে বুলিয়ান মানগুলি প্রয়োজন সেই প্রসঙ্গে যেগুলিতে রূপান্তরিত হতেbool পারে তা আমি বলতে চাই । এই ঠিক কোড প্রশ্নে ঘটছে।
প্রিটোরিয়ান

4
@ প্রেটেরিয়ান আমি যে বক্তব্যটি তৈরি করতে চাইছি তা হ'ল মানটি "অন্তর্নিহিত রূপান্তর" শব্দটির খুব নির্দিষ্ট অর্থ অর্পণ করে এবং এটি "প্রসঙ্গত রূপান্তর" থেকে পৃথক পৃথক পৃথক পৃথক পৃথক পৃথক অর্থও যার একটি খুব নির্দিষ্ট অর্থ রয়েছে। এখানে "ইস-এ" সম্পর্ক নেই। আমি বুঝতে পেরেছি যে প্রাথমিকভাবে সম্ভবত অবিলম্বে স্পষ্ট / স্পষ্ট / প্রাসঙ্গিক রূপান্তরগুলির মধ্যে পার্থক্যটি জানতে হবে না, তবে পরে পুরানো অভ্যাসগুলি ভেঙে ফেলার চেয়ে অবচেতনভাবে সঠিক শব্দগুলি শেখা ভাল better
বিক্রিস্ট

22

এখানে দেখুন http://www.cplusplus.com/references/functional/function/operator_bool/

উদাহরণ

// function::operator bool example
#include <iostream>     // std::cout
#include <functional>   // std::function, std::plus

int main () {
  std::function<int(int,int)> foo,bar;
  foo = std::plus<int>();

  foo.swap(bar);

  std::cout << "foo is " << (foo ? "callable" : "not callable") << ".\n";
  std::cout << "bar is " << (bar ? "callable" : "not callable") << ".\n";

  return 0;
}

আউটপুট

foo কল করা যায় না।

বার কলযোগ্য


31
আমি মনে করি এই উত্তরটি ছাড়া আরও স্পষ্ট হবে swap()। আমি ভাবছিলাম আউটপুটটি পিছন দিকে ছিল যতক্ষণ না আমি এটি উপলব্ধি করেছি।
cp.engr

0

(আমাকে একটি পরিষ্কার উত্তর দিতে দিন।)

কোনও std::functionখালি আছে কিনা তা আপনি পরীক্ষা করতে পারেন std::function::operator bool

সত্য: যদি বস্তু কলযোগ্য হয়।
মিথ্যা: অন্যথায় (বস্তুটি খালি ফাংশন)

উদাহরণ

#include <iostream>
#include <functional>

int main ()
{
    std::function<int(int,int)> foo = std::plus<int>();//assigned: not empty
    std::function<int(int,int)> bar;//not assigned: empty

    std::cout << "foo is " << (foo ? "not empty" : "empty") << ".\n";
    std::cout << "bar is " << (bar ? "not empty" : "empty") << ".\n";

    return 0;
}

আউটপুট

foo খালি নেই।
বার খালি।


4
আপনার ফলাফলের স্ট্রিংগুলি অদলবদল করা হয়েছে।
সোফিত

@ সোফিট আপনি কি নিশ্চিত? ;)
zwcloud

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