c++ - একটি ল্যাম্বদা ফাংশন ওভারলোড করুন




lambda overloading (2)

না, আপনি ল্যাম্বডাকে ওভারলোড করতে পারবেন না!

ল্যাম্বডাস বেনামে ফান্টেক্টর (অর্থাত্ নামবিহীন ফাংশন অবজেক্টস), এবং সাধারণ ফাংশন নয়। অতএব, objects অবজেক্টগুলি ওভারলোড করা সম্ভব নয়। আপনি মূলত যা করার চেষ্টা করছেন তা প্রায়

struct <some_name>
{
    int operator()(int idx) const
    {
        return {}; // some int
    }
}translate; // >>> variable name

struct <some_name>
{
    int operator()(char idx) const
    {
        return {}; // some int
    }
}translate; // >>> variable name

যা সম্ভব নয়, কারণ একই পরিবর্তনশীল নামটি C ++ এ পুনরায় ব্যবহার করা যায় না।

যাইহোক, সি ++ 17 এ আমাদের if constexpr যার মাধ্যমে কেউ একমাত্র শাখাটি সংকলন করতে পারে যা সংকলনের সময় সত্য।

সম্ভাব্য সমাধানগুলি হ'ল অর্থ:

ভেরাবেব টেম্পলেট ব্যবহার করে আপনি এর মতো কিছু করতে পারেন। ( অনলাইন লাইভ ডেমো দেখুন )

#include <type_traits> // std::is_same_v

template<typename T>
constexpr auto translate = [](T idx) 
{
    if constexpr (std::is_same_v<T, int>)
    {
        constexpr static int table[8]{ 7,6,5,4,3,2,1,0 };
        return table[idx];
    }
    else if constexpr (std::is_same_v<T, char>)
    {
        std::map<char, int> table{ {'a', 0}, {'b', 1}, {'c', 2}, {'d', 3}, {'e', 4}, {'f', 5}, {'g', 6}, {'h', 7} };
        return table[idx];
    }
};

এবং এটি পছন্দ করুন

int r = translate<int>(line[0]);
int c = translate<char>(line[1]);

জেনেরিক ল্যাম্বদা ব্যবহার করে (যেহেতু সি ++ ১৪ ), উপরেরগুলি হবে: ( অনলাইনে একটি লাইভ ডেমো দেখুন )

#include <type_traits> // std::is_same_v

constexpr auto translate = [](auto idx) 
{
    if constexpr (std::is_same_v<decltype(idx), int>)
    {
        constexpr static int table[8]{ 7,6,5,4,3,2,1,0 };
        return table[idx];
    }
    else if constexpr (std::is_same_v<decltype(idx), char>)
    {
        std::map<char, int> table{ {'a', 0}, {'b', 1}, {'c', 2}, {'d', 3}, {'e', 4}, {'f', 5}, {'g', 6}, {'h', 7} };
        return table[idx];
    }
};

এবং এখন যেমন করে ল্যাম্বডাকে কল করুন:

int r = translate(static_cast<int>(line[0]));
int c = translate(static_cast<char>(line[1]));

কিভাবে একটি সাধারণ স্থানীয় ল্যাম্বদা ফাংশন ওভারলোড করবেন?

মূল সমস্যার এসএসই:

#include <iostream>
#include <map>

void read()
{
    static std::string line;
    std::getline(std::cin, line);

    auto translate = [](int idx)
    {
        constexpr static int table[8]{ 7,6,5,4,3,2,1,0 };
        return table[idx];
    };

    auto translate = [](char c)
    {
        std::map<char, int> table{ {'a', 0}, {'b', 1}, {'c', 2}, {'d', 3},
                                             {'e', 4}, {'f', 5}, {'g', 6}, {'h', 7} };
        return table[c];
    };

    int r = translate(static_cast<int>(line[0]));
    int c = translate(static_cast<char>(line[1]));
    std::cout << r << c << std::endl;
}

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

ত্রুটি বার্তা

error: conflicting declaration 'auto translate'
note: previous declaration as 'read()::<lambda(int)> translate'

ব্যবহারকারীর ইনপুট পরীক্ষা না করে দয়া করে মনে করবেন না, এটি একটি এসএসই।


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

তবে আপনি ওভারলোডেড operator() দিয়ে একটি ফান্টারের সংজ্ঞা দিতে পারেন। এটি সম্ভব হলে ল্যাম্বডাসের কাছ থেকে ঠিক কী পাবেন। আপনি কেবল ক্ষুদ্র বাক্য গঠন পেতে পারেন না।

কিছুটা এইরকম:

void read()
{
    static std::string line;

    struct translator {
          int operator()(int idx) { /* ... */ }
          int operator()(char x)  { /* ... */ }
    };
    translator translate;


    std::getline(std::cin, line);

    int r = translate(static_cast<int>(line[0]));
    int c = translate(static_cast<char>(line[1]));

    std::cout << r << c << std::endl;
}




function-object