প্রত্যাবর্তনের ধরণটি স্পষ্টভাবে উল্লেখ করেও ল্যাম্বডায় কল দ্বিধাহীন


11

একটি ওভারলোডেড ক্রিয়াকলাপ উভয় ফান্টারের মধ্যে নেওয়া উচিত, ল্যাম্বডা ধরণটি নির্ধারণযোগ্য (মাপের জন্য একটি std::function(I'm ালাই যদি আমি ভুল হয়ে থাকি তবে দয়া করে)। সংজ্ঞায়িত? ( [&]() -> Type {})

দয়া করে নোট করুন, আমার বর্তমান সমাধানের জন্য আমার ক্যাপচার-বাই-রেফারেন্স দরকার, এজন্য কোডটিতে এর জন্য যুক্তি রয়েছে।

নিম্নলিখিত উদাহরণটি সমস্যার বর্ণনা দেয়:

#include <iostream>
#include <string>    
#include <functional>

void do_some(std::function<void(int)> thing) 
{
   thing(5);
}

void do_some(std::function<bool(int)> thing)
{
   if (thing(10)) 
   {
      std::cout << "it's true!" << std::endl;
   }
}

int main()
{
   int local_to_be_modified = 0;
   do_some(
      [&](int in)
      {
         local_to_be_modified = in;
         std::cout << "This is void-" << std::endl;
      }
   );
   do_some(
      [&](int in) -> bool
      { 
         // error: call to 'do_some' is ambiguous
         local_to_be_modified += in;
         std::cout << "This is bool-" << std::endl;
         return true;
      }
   );
}

6
কারণ std::function<void(int)>এমন কোনও ল্যাম্বদা থেকেও নির্মিত যেতে পারে যা কিছু ফেরত দেয় (যার ফলে ফেরতের মান উপেক্ষা করা হয়)।
হলিব্ল্যাকগেটক

1
একটি সরু হিসাবে, স্পষ্টভাবে উল্লেখ করা যে সেই ল্যাম্বদা ফেরতের ধরণটি হুবহু কিছুই করে না।
উত্সাহক

উত্তর:


8

কারণ ২ য় ল্যাম্বডা এক্সপ্রেশনটি প্রত্যাবর্তনগুলি boolউভয় std::function<void(int)>এবং std::function<bool(int)>অন্তর্নিহিতভাবে রূপান্তর করতে পারে ।

std::function রূপান্তরকারী কনস্ট্রাক্টর রয়েছে:

template< class F >
function( F f );

এই কনস্ট্রাক্টর আর্গুমেন্ট ধরণের আরগস ... এবং রিটার্ন টাইপ আর এর জন্য কল করা না হলে ওভারলোড রেজোলিউশনে অংশ নেয় না (সি ++ 14 থেকে

কলযোগ্য সংজ্ঞা হিসাবে ,

নিম্নলিখিত অভিব্যক্তিগুলি অবশ্যই বৈধ হতে হবে:

INVOKE<R>(f, std::declval<ArgTypes>()...)

যেখানে ইনভোক (এফ, টি 1, টি 2, ..., টিএন) এমনভাবে সংজ্ঞায়িত করা হয় static_cast<void>(INVOKE(f, t1, t2, ..., tN))যেন আর সম্ভবত সিভি-যোগ্য void, অন্যথায় ইনভোক (এফ, টি 1, টি 2, ..., টিএন) , স্পষ্টভাবে আর তে রূপান্তরিত হয়

লক্ষ্য করুন 2nd ল্যামডা ফেরার boolজন্য std::function<void(int)>, যেমন উপরে দেখানো, static_cast<void>(INVOKE(f, t1, t2, ..., tN))একটি বৈধ অভিব্যক্তি (ফিরে আসেন boolশুধু রূপান্তরিত হয় void)। তারপরে এটি std::function<void(int)>স্পষ্টত রূপান্তর করতে পারে এবং অস্পষ্টতা সমস্যার কারণ হতে পারে ।


6

আপনি static_castসঠিকভাবে ল্যাম্বডাকে যথাযথভাবে করতে পারেন

using FunBoolRet = std::function<bool(int)>;

do_some(static_cast<FunBoolRet >([&](int in) 
   {
      local_to_be_modified += in;
      std::cout << "This is bool-" << std::endl;
      return true;
   }));

অথবা ল্যাম্বডাকে সঠিক std::function<bool(int)>টাইপ করে সংরক্ষণ করুন এবং ফাংশনটিতে পাস করুন (যদি do_some(lmda)অনেকবার ডাকা উচিত)

FunBoolRet lmda = [&](int in)
{
    local_to_be_modified += in;
    std::cout << "This is bool-" << std::endl;
    return true;
};    
do_some(lmda); // pass the lambda

অথবা @ ম্যাক্স ল্যাংহোফের পরামর্শ অনুসারে চলতে চলতে ল্যাম্বদাstd::function<bool(int)> থেকে কেবল নির্মাণ করুন

do_some(FunBoolRet{
   [&](int in) 
   {
      local_to_be_modified += in;
      std::cout << "This is bool-" << std::endl;
      return true;
   }
});

আপনি এড়িয়ে যেতে পারেন static_castএবং এটি std::functionথেকে সরাসরি একটি নির্মাণ করতে পারেন । যাইহোক যাইহোক প্রকৃত রূপান্তরকালে এটি ঘটে।
ম্যাক্স ল্যাঙ্গোফ

আমার বক্তব্যটি হ'ল আপনি আক্ষরিকভাবে কেবল static_cast<শেষ >এবং শেষ সরিয়ে ফেলতে পারেন এবং এটি একই জিনিসটি করবে তবে কম টাইপ করে। এটির জন্য আরও লাইন বা কোনও কিছুর প্রয়োজন নেই। Godbolt.org/z/fQTqF4
ম্যাক্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.