স্যুইচ স্টেটমেন্ট স্ট্রিংগুলিতে প্রয়োগ করা যাবে না কেন?


227

নিম্নলিখিত কোডটি সংকলন করে এর ত্রুটি পেয়েছি type illegal

int main()
{
    // Compilation error - switch expression of type illegal
    switch(std::string("raj"))
    {
    case"sda":
    }
}

আপনি পারেন স্ট্রিং ব্যবহার করতে পারবেন না switchবা case। কেন? স্ট্রিংগুলিতে স্যুইচ করার অনুরূপ যুক্তি সমর্থন করার জন্য এমন কোনও সমাধান রয়েছে যা কার্যকরভাবে কাজ করে?


6
ম্যাক্রোর পেছনে এনাম ম্যাপের নির্মাণকে আড়াল করে এমন কোনও উত্সাহী বিকল্প রয়েছে কি?
বালকি

@ বাল্কি আমি বৃদ্ধির বিষয়ে নিশ্চিত নই তবে এই জাতীয় ম্যাক্রোগুলি লেখা সহজ to Qt এর ক্ষেত্রে আপনি ম্যাপিংটি লুকিয়ে রাখতে পারেনQMetaEnum
ফুচলভি

উত্তর:


189

টাইপ সিস্টেমের সাথে করার কারণ। সি / সি ++ প্রকৃতপক্ষে কোনও ধরণের স্ট্রিং সমর্থন করে না। এটি ধ্রুবক চর অ্যারের ধারণাকে সমর্থন করে তবে এটি কোনও স্ট্রিংয়ের ধারণাটি পুরোপুরি বুঝতে পারে না।

একটি স্যুইচ স্টেটমেন্টের জন্য কোড উত্পন্ন করতে সংকলকটি অবশ্যই বুঝতে হবে এটি দুটি মান সমান হওয়ার জন্য কী বোঝায়। Ints এবং enums মত আইটেমের জন্য, এটি একটি তুচ্ছ বিট তুলনা। তবে সংকলকটি কীভাবে 2 টি স্ট্রিংয়ের মান তুলনা করে? কেস সংবেদনশীল, সংবেদনশীল, সংস্কৃতি সচেতন, ইত্যাদি ... স্ট্রিংয়ের সম্পূর্ণ সচেতনতা ছাড়াই এর সঠিক উত্তর দেওয়া যায় না।

অতিরিক্তভাবে, সি / সি ++ স্যুইচ স্টেটমেন্টগুলি সাধারণত শাখা টেবিল হিসাবে উত্পন্ন হয় । স্ট্রিং স্টাইলের স্যুইচের জন্য কোনও ব্রাঞ্চ টেবিল তৈরি করা প্রায় সহজ নয়।


11
শাখা সারণী যুক্তি প্রয়োগ করা উচিত নয় - এটি সংকলক লেখকের কাছে কেবলমাত্র একটি সম্ভাব্য পন্থা। একটি প্রোডাকশন সংকলকটির জন্য, একজনকে প্রায়শই স্যুইচের জটিলতার উপর নির্ভর করে বেশ কয়েকটি পন্থা ব্যবহার করতে হয়।
থামাল

5
@ প্লিন্থ, আমি এটি বেশিরভাগ historicalতিহাসিক কারণে এখানে রেখেছি। প্রচুর "সি / সি ++ এটি করে কেন" প্রশ্নগুলির অনেকগুলি সহজেই সংকলকের ইতিহাসে উত্তর দেওয়া যায়। তারা এটি লেখার সময় সি এর মহিমান্বিত সমাবেশ ছিল এবং তাই সত্যই স্যুইচ করা ছিল একটি সুবিধাজনক শাখা টেবিল।
জেয়ার্ডপাড়

113
আমি ভোট দিয়েছি কারণ আমি বুঝতে পারি না যে সংকলকটি কীভাবে স্টেটমেন্টগুলিতে 2 টি স্ট্রিংয়ের মান তুলনা করতে পারে তবে সুইচ স্টেটমেন্টগুলিতে একই জিনিসটি করার উপায়টি ভুলে যায়।

15
আমি মনে করি না যে প্রথম 2 অনুচ্ছেদগুলি বৈধ কারণ। বিশেষত সি ++ 14 থেকে যখন std::stringআক্ষরিক যোগ করা হয়েছিল। এটি বেশিরভাগ historicalতিহাসিক। কিন্তু এক সমস্যা মনে আসে যে যে ভাবে সাথে আছেন switchবর্তমানে কাজ করে, নকল caseগুলি আবশ্যক কম্পাইল-সময়ে সনাক্ত করা; তবে স্ট্রিংয়ের জন্য এটি এত সহজ নাও হতে পারে (রান-টাইম লোকাল নির্বাচন ইত্যাদি বিবেচনা করে)। আমি মনে করি যে এই জাতীয় জিনিসটির জন্য constexprমামলাগুলির প্রয়োজন হবে , বা অনির্দিষ্ট আচরণে যুক্ত করা উচিত (এমন কোনও জিনিস যা আমরা করতে চাই না)।
এমএম

8
কনস্টের চর অ্যারের সাথে দুটি std::stringমান বা এমনকি কোনও std::stringএকটিকে কীভাবে তুলনা করা যায় তার একটি স্পষ্ট সংজ্ঞা রয়েছে (যথা অপারেটর == ব্যবহার করে) কোনও অপারেটর সরবরাহকারী কোনও প্রকারের জন্য সংকলকটিকে একটি স্যুইচ বিবৃতি উত্পন্ন করা থেকে বিরত রাখতে পারে এমন কোনও প্রযুক্তিগত কারণ নেই। এটি লেবেলগুলির আজীবন সম্পর্কিত বিষয়গুলি সম্পর্কে কিছু প্রশ্ন খুলবে তবে এই সমস্ত কিছুই মূলত একটি ভাষা নকশার সিদ্ধান্ত, কোনও প্রযুক্তিগত অসুবিধা নয়।
মাইক এমবি

60

পূর্বে উল্লিখিত হিসাবে, সংকলকগণ switchযখনই সম্ভব যখনই ও (1) সময়সীমার নিকটস্থ বিবৃতিগুলিকে অনুকূল করে তোলে এমন সন্ধানের টেবিলগুলি তৈরি করতে পছন্দ করে । এটিকে একত্রিত করুন যে সি ++ ভাষার স্ট্রিং টাইপ নেই - std::stringস্ট্যান্ডার্ড লাইব্রেরির অংশ যা প্রতি সেও ভাষার অংশ নয়।

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

enum string_code {
    eFred,
    eBarney,
    eWilma,
    eBetty,
    ...
};

string_code hashit (std::string const& inString) {
    if (inString == "Fred") return eFred;
    if (inString == "Barney") return eBarney;
    ...
}

void foo() {
    switch (hashit(stringValue)) {
    case eFred:
        ...
    case eBarney:
        ...
    }
}

সুস্পষ্ট অপ্টিমাইজেশনের একটি গুচ্ছ রয়েছে যা সি সংকলকটি একটি স্যুইচ স্টেটমেন্ট দিয়ে কী করবে তা মেনে চলে ... কীভাবে ঘটে তা মজার।


15
এটি সত্যই হতাশার কারণ আপনি আসলে হ্যাশ করছেন না। আধুনিক সি ++ এর সাহায্যে আপনি কনসেক্সপ্রেশ হ্যাশ ফাংশনটি ব্যবহার করে সংকলনের সময় আসলে হ্যাশ করতে পারেন। দুর্ভাগ্যক্রমে সিঁড়িটি চলতে থাকলে আপনার সমাধানটি দেখতে পরিষ্কার দেখাচ্ছে তবে মশালাগুলি সমস্ত খারাপ asty নীচের মানচিত্রের সমাধানগুলি আরও ভাল হবে এবং পাশাপাশি ফাংশন কলটি এড়ানো হবে। অতিরিক্তভাবে দুটি মানচিত্র ব্যবহার করে ত্রুটি লগিংয়ের জন্য আপনি পাঠ্য অন্তর্নির্মিত করতে পারেন।
ডার্ক বেসার

এছাড়াও আপনি lambdas সঙ্গে enum এড়াতে পারেন: stackoverflow.com/a/42462552/895245
সিরো Santilli郝海东冠状病六四事件法轮功

হ্যাশিট কি একটি কনটেক্সারপ ফাংশন হতে পারে? দেওয়া হয়েছে যে আপনি একটি স্ট্যান্ড :: স্ট্রিংয়ের পরিবর্তে কনস্টের চরে পাস করেছেন।
ভিক্টর স্টোন

কিন্তু কেন? আপনি যদি একটি স্যুইচের শীর্ষে if স্টেটমেন্ট কার্যকর করতে পারেন তবে সমস্ত সময় ব্যবহার করতে পারেন। উভয়টিরই ন্যূনতম প্রভাব রয়েছে, তবে যদি স্যুইচ সহ পারফরম্যান্স সুবিধাগুলি যদি-অন্যরূপ অনুসন্ধানের দ্বারা মুছে ফেলা হয়। কেবলমাত্র যদি অন্য-কিছু ব্যবহার করা যায় তবে গতিতে দ্রুত হওয়া উচিত, তবে আরও গুরুত্বপূর্ণ, উল্লেখযোগ্যভাবে খাটো।
জো

20

সি ++

কনটেক্সপ্র হ্যাশ ফাংশন:

constexpr unsigned int hash(const char *s, int off = 0) {                        
    return !s[off] ? 5381 : (hash(s, off+1)*33) ^ s[off];                           
}                                                                                

switch( hash(str) ){
case hash("one") : // do something
case hash("two") : // do something
}

1
আপনাকে নিশ্চিত করতে হবে যে আপনার কেসের কোনও হ্যাশ একই মানের নয়। এবং তারপরেও আপনার কিছু ভুল থাকতে পারে যেখানে অন্যান্য স্ট্রিং যা হ্যাশ করেছে, উদাহরণস্বরূপ, হ্যাশের একই মান ("একটি") আপনার সুইচটিতে ভুলভাবে প্রথম "কিছু" করবে।
ডেভিড লজং ম্যাডিসন স্টেলার l

আমি জানি, তবে এটির যদি একই মান হয় তবে এটি সংকলন করবে না এবং আপনি এটি সময়মতো লক্ষ্য করবেন।
নিক

ভাল কথা - তবে এটি আপনার স্যুইচের অংশ নয় এমন অন্যান্য স্ট্রিংয়ের জন্য হ্যাশ সংঘাতের সমাধান করে না। কিছু ক্ষেত্রে এর পক্ষে কিছু আসে যায় না, তবে এটি যদি জেনেরিক "গো-টু" সমাধান হয় তবে আমি এটি কোনও সুরক্ষার সমস্যা বা এর মতো হতে পারে তা কল্পনা করতে পারি some
ডেভিড লজং ম্যাডিসন স্টারার

7
operator ""কোডটি আরও সুন্দর করতে আপনি যুক্ত করতে পারেন । constexpr inline unsigned int operator "" _(char const * p, size_t) { return hash(p); }এবং এটি case "Peter"_: break; ডেমো
hare1039

15

সি ++ এর 11 টি আপডেট আপাতদৃষ্টিতে @ মারমু কর্প্পের উপরের নয় তবে http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4067/Switch-on-Strings-in-C.htm

স্ট্রিং এবং ক্লাস এনামের মধ্যে রূপান্তর করতে দুটি মানচিত্র ব্যবহার করে (প্লেইন এনামের চেয়ে ভাল কারণ এর মানগুলি এর অভ্যন্তরে বিভক্ত থাকে, এবং দুর্দান্ত ত্রুটির বার্তাগুলির জন্য বিপরীত অনুসন্ধান)।

কোডগুরু কোডে স্ট্যাটিকের ব্যবহার ইনিশিয়ালার তালিকাগুলির জন্য কম্পাইলার সমর্থনের মাধ্যমে সম্ভব যার অর্থ ভিএস 2013 প্লাস। জিসিসি 4.8.1 এটির সাথে ঠিক ছিল, এটি কতটা সামঞ্জস্যপূর্ণ হবে তা নিশ্চিত নয়।

/// <summary>
/// Enum for String values we want to switch on
/// </summary>
enum class TestType
{
    SetType,
    GetType
};

/// <summary>
/// Map from strings to enum values
/// </summary>
std::map<std::string, TestType> MnCTest::s_mapStringToTestType =
{
    { "setType", TestType::SetType },
    { "getType", TestType::GetType }
};

/// <summary>
/// Map from enum values to strings
/// </summary>
std::map<TestType, std::string> MnCTest::s_mapTestTypeToString
{
    {TestType::SetType, "setType"}, 
    {TestType::GetType, "getType"}, 
};

...

std::string someString = "setType";
TestType testType = s_mapStringToTestType[someString];
switch (testType)
{
    case TestType::SetType:
        break;

    case TestType::GetType:
        break;

    default:
        LogError("Unknown TestType ", s_mapTestTypeToString[testType]);
}

আমার নোট করা উচিত যে পরে আমি স্ট্রিং লিটারালগুলির সংকলন এবং সময়ের গণনা (সি ++ 14 বা 17 মনে করি) এর জন্য একটি সমাধান পেয়েছি যেখানে আপনি সংকলন সময়ে কেস স্ট্রিংগুলি হ্যাশ করতে পারেন এবং রানটাইমটিতে সুইচ স্ট্রিং হ্যাশ করতে পারেন। সত্যিই দীর্ঘ সুইচগুলির পক্ষে এটি সার্থক হতে পারে তবে এটির ক্ষেত্রে অবশ্যই কম পিছনে সামঞ্জস্যপূর্ণ।
ডার্ক বেস্টার

আপনি এখানে সংকলন-সময় সমাধান ভাগ করতে পারেন? ধন্যবাদ!
কিড

12

সমস্যাটি হ'ল অপটিমাইজেশনের কারণে সি ++ এ স্যুইচ স্টেটমেন্ট আদিম ধরণের ব্যতীত অন্য কিছুতে কাজ করে না এবং আপনি কেবল সেগুলি সংকলনের সময় স্থিরতার সাথে তুলনা করতে পারেন।

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

এটি ঘুরে দেখার জন্য, আমি আশঙ্কা করছি যে বিবৃতি দিলে আপনাকে অবলম্বন করতে হবে।


স্ট্রিংগুলির সাথে কাজ করতে পারে এমন একটি স্যুইচ বিবৃতিটির একটি অনুকূলিত সংস্করণ অবশ্যই সম্ভব। তারা আদিম ধরণের জন্য তারা একই কোড পাথটি পুনরায় ব্যবহার করতে পারে না তার অর্থ এই নয় যে তারা std::stringভাষাতে অন্যদের প্রথম নাগরিক তৈরি করতে পারে না এবং দক্ষ অ্যালগরিদমের সাহায্যে স্যুইচ বিবৃতিতে তাদের সমর্থন করে।
ceztko

10

std::map এনাম ছাড়া সি ++ 11 ল্যাম্বডাস প্যাটার্ন

unordered_mapসম্ভাব্য amorised জন্য O(1): সি ++ এ একটি হ্যাশম্যাপ ব্যবহার করার সবচেয়ে ভাল উপায় কী?

#include <functional>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>

int main() {
    int result;
    const std::unordered_map<std::string,std::function<void()>> m{
        {"one",   [&](){ result = 1; }},
        {"two",   [&](){ result = 2; }},
        {"three", [&](){ result = 3; }},
    };
    const auto end = m.end();
    std::vector<std::string> strings{"one", "two", "three", "foobar"};
    for (const auto& s : strings) {
        auto it = m.find(s);
        if (it != end) {
            it->second();
        } else {
            result = -1;
        }
        std::cout << s << " " << result << std::endl;
    }
}

আউটপুট:

one 1
two 2
three 3
foobar -1

ভিতরে অভ্যন্তরীণ পদ্ধতি ব্যবহার static

ক্লাসের অভ্যন্তরে এই প্যাটার্নটি দক্ষতার সাথে ব্যবহার করতে, ল্যাম্বডা মানচিত্রটি স্ট্যাটিকভাবে শুরু করুন, অন্যথায় আপনি O(n)স্ক্র্যাচ থেকে এটি তৈরির জন্য প্রতিবার অর্থ প্রদান করেন ।

এখানে আমরা {}একটি staticপদ্ধতি ভেরিয়েবলের সূচনা দিয়ে পালাতে পারি : ক্লাস পদ্ধতিতে স্ট্যাটিক ভেরিয়েবল , তবে আমরা বর্ণিত পদ্ধতিগুলিও ব্যবহার করতে পারি: সি ++স্থিতিশীল নির্মাণকারী? আমার প্রাইভেট স্ট্যাটিক অবজেক্টগুলি আরম্ভ করতে হবে

ল্যাম্বডা প্রসঙ্গে ক্যাপচারটিকে [&]আর্গুমেন্টে রূপান্তর করা প্রয়োজন ছিল বা এটি অপরিজ্ঞাত করা হত : কনস্ট স্ট্যাটিক অট ল্যাম্বদা রেফারেন্স দ্বারা ক্যাপচারের সাথে ব্যবহৃত হয়েছে

উপরের মত একই আউটপুট উত্পাদন করে এমন উদাহরণ:

#include <functional>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>

class RangeSwitch {
public:
    void method(std::string key, int &result) {
        static const std::unordered_map<std::string,std::function<void(int&)>> m{
            {"one",   [](int& result){ result = 1; }},
            {"two",   [](int& result){ result = 2; }},
            {"three", [](int& result){ result = 3; }},
        };
        static const auto end = m.end();
        auto it = m.find(key);
        if (it != end) {
            it->second(result);
        } else {
            result = -1;
        }
    }
};

int main() {
    RangeSwitch rangeSwitch;
    int result;
    std::vector<std::string> strings{"one", "two", "three", "foobar"};
    for (const auto& s : strings) {
        rangeSwitch.method(s, result);
        std::cout << s << " " << result << std::endl;
    }
}

3
নোট করুন যে এই পদ্ধতির এবং একটি switchবিবৃতি মধ্যে পার্থক্য আছে । switchবিবৃতিতে কেস মানগুলির সদৃশ একটি সংকলন সময় ব্যর্থতা। std::unordered_mapনিঃশব্দে ব্যবহার করে সদৃশ মানগুলি গ্রহণ করে ।
ডি.শোলে

6

সি ++ এবং সি-তে স্যুইচগুলি কেবল পূর্ণসংখ্যার ধরণের ক্ষেত্রে কাজ করে। পরিবর্তে অন্য কোনও মই ব্যবহার করুন। সি ++ স্পষ্টতই স্ট্রিংগুলির জন্য কিছু ধরণের সুইচ স্টেটমেন্ট বাস্তবায়ন করতে পারত - আমি অনুমান করি যে এটি কেউ উপযুক্ত বলে মনে করেনি এবং আমি তাদের সাথে একমত হই।


সম্মত হয়েছে, তবে কী আপনি কী জানেন এটি কী ব্যবহার করা সম্ভব করে নি
Yesraaj

ইতিহাস? প্রকৃত সংখ্যা, পয়েন্টার এবং স্ট্রোকগুলি (সি এর কেবলমাত্র অন্যান্য ডেটা ধরণের) স্যুইচ করা সানসে করে না, সুতরাং সি এটি পূর্ণসংখ্যার মধ্যে সীমাবদ্ধ করে।

বিশেষত যদি আপনি এমন ক্লাসগুলি স্যুইচ করেন যা অন্তর্নিহিত রূপান্তরগুলিকে অনুমতি দেয় তবে আপনার একবারে খুব ভাল সময় আসবে।
শার্পথুথ

6

কেন না? আপনি সমতুল্য সিনট্যাক্স এবং একই শব্দার্থক সহ স্যুইচ বাস্তবায়ন ব্যবহার করতে পারেন । Cভাষা আদৌ বস্তু এবং স্ট্রিং বস্তু নেই, কিন্তু স্ট্রিং Cহয় নাল সমাপ্ত পয়েন্টার দ্বারা সমর্থিত স্ট্রিং। C++ভাষা বস্তু comparision বা বস্তু equalities, চেক করার জন্য জমিদার ফাংশন করতে সম্ভাবনা আছে। হিসাবে Cহিসাবে C++যথেষ্ট নমনীয় জন্য স্ট্রিং এমন সুইচ আছে হয় C ভাষা ও যেকোনো ধরনের অবজেক্টের জন্য যে সমর্থন comparaison বা চেক জন্য সমতা C++ভাষা। এবং আধুনিক C++11এই সুইচ বাস্তবায়ন যথেষ্ট কার্যকর করতে অনুমতি দেয়।

আপনার কোডটি এর মতো হবে:

std::string name = "Alice";

std::string gender = "boy";
std::string role;

SWITCH(name)
  CASE("Alice")   FALL
  CASE("Carol")   gender = "girl"; FALL
  CASE("Bob")     FALL
  CASE("Dave")    role   = "participant"; BREAK
  CASE("Mallory") FALL
  CASE("Trudy")   role   = "attacker";    BREAK
  CASE("Peggy")   gender = "girl"; FALL
  CASE("Victor")  role   = "verifier";    BREAK
  DEFAULT         role   = "other";
END

// the role will be: "participant"
// the gender will be: "girl"

উদাহরণস্বরূপ std::pairsবা যে কোনও স্ট্রাক্ট বা ক্লাস যা সাম্যতা ক্রিয়াকলাপকে সমর্থন করে (বা দ্রুত মোডের জন্য কোমরিজেনস ) আরও জটিল ধরণের ব্যবহার করা সম্ভব ।

বৈশিষ্ট্য

  • তুলনা বা সমতা যাচাই করে এমন কোনও ধরণের ডেটা সমর্থন করে
  • ক্যাসকেডিং নেস্টেড সুইচ স্টেটম্যানগুলি তৈরির সম্ভাবনা।
  • কেস স্টেটমেন্টের মাধ্যমে ভেঙে পড়ার সম্ভাবনা
  • অবিচ্ছিন্ন কেস এক্সপ্রেশন ব্যবহার করার সম্ভাবনা
  • ট্রি সন্ধানের সাথে দ্রুত স্ট্যাটিক / ডায়নামিক মোড সক্ষম করা সম্ভব (সি ++ 11 এর জন্য)

ভাষা স্যুইচ সহ সিনট্যাক্স পার্থক্য

  • বড় হাতের কীওয়ার্ড
  • CASE বিবৃতি জন্য প্রথম বন্ধনী প্রয়োজন
  • সেমিকোলন ';' বিবৃতি শেষে অনুমোদিত নয়
  • CASE বিবৃতিতে কোলন ':' অনুমোদিত নয়
  • CASE স্টেটমেন্টের শেষে BREAK বা ফল কীওয়ার্ডের একটি দরকার

জন্য C++97ভাষা রৈখিক অনুসন্ধান ব্যবহার করা হয়েছে। জন্য C++11এবং আরো আধুনিক ব্যবহার সম্ভব quickমোড wuth গাছ অনুসন্ধান যেখানে রিটার্ন যদি বিবৃতি হয়ে মঞ্জুরি নেই। Cভাষা বাস্তবায়ন বিদ্যমান যেখানে char*ধরন এবং শূন্য-সমাপ্ত স্ট্রিং comparisions ব্যবহার করা হয়।

এই স্যুইচ বাস্তবায়ন সম্পর্কে আরও পড়ুন ।


6

সহজতম কন্টেইনারটি ব্যবহার করে কোনও পরিবর্তন যুক্ত করতে (আদেশযুক্ত মানচিত্রের প্রয়োজন নেই) ... আমি কোনও এনাম নিয়ে বিরক্ত করব না - কেবলমাত্র সুইচের আগে ধারক সংজ্ঞাটি রেখে দিন যাতে কোন সংখ্যাটি প্রতিনিধিত্ব করে তা সহজেই দেখা যায় কোন ক্ষেত্রে।

এটিতে একটি হ্যাশ লুক রয়েছে unordered_mapএবং intস্যুইচ স্টেটমেন্টটি ড্রাইভ করতে সম্পর্কিত ব্যবহার করে । বেশ দ্রুত হওয়া উচিত। নোট যে atপরিবর্তে ব্যবহৃত হয় [], আমি যেমন ধারক তৈরি করেছি const। ব্যবহার []করা বিপজ্জনক হতে পারে - যদি স্ট্রিং মানচিত্রে না থাকে তবে আপনি একটি নতুন ম্যাপিং তৈরি করবেন এবং অবধারিত ফলাফল বা ক্রমাগত ক্রমবর্ধমান মানচিত্রের সমাপ্তি ঘটতে পারে।

নোট at()করুন স্ট্রিং মানচিত্রে না থাকলে ফাংশনটি একটি ব্যতিক্রম ছুঁড়ে দেবে। সুতরাং আপনি প্রথমে ব্যবহার করে পরীক্ষা করতে চাইতে পারেন count()

const static std::unordered_map<std::string,int> string_to_case{
   {"raj",1},
   {"ben",2}
};
switch(string_to_case.at("raj")) {
  case 1: // this is the "raj" case
       break;
  case 2: // this is the "ben" case
       break;


}

একটি অনির্ধারিত স্ট্রিংয়ের জন্য একটি পরীক্ষা সহ সংস্করণটি নিম্নলিখিত:

const static std::unordered_map<std::string,int> string_to_case{
   {"raj",1},
   {"ben",2}
};
// in C++20, you can replace .count with .contains
switch(string_to_case.count("raj") ? string_to_case.at("raj") : 0) {
  case 1: // this is the "raj" case
       break;
  case 2: // this is the "ben" case
       break;
  case 0: //this is for the undefined case

}

4

আমি মনে করি কারণটি সি স্ট্রিংগুলি আদিম ধরণের নয়, যেমন টমজেন বলেছিলেন, একটি স্ট্রিংকে চর অ্যারে হিসাবে মনে করুন, সুতরাং আপনি এই জাতীয় জিনিসগুলি করতে পারবেন না:

switch (char[]) { // ...
switch (int[]) { // ...

3
এটি সন্ধান না করে একটি চরিত্রের অ্যারে সম্ভবত একটি চরকে অবনমিত হতে পারে, যা সরাসরি একটি অবিচ্ছেদ্য ধরণের রূপান্তর করে। সুতরাং, এটি ভালভাবে সংকলন করতে পারে, তবে এটি অবশ্যই যা চায় তা করবে না।
ডেভিড থর্নলি

3

সি ++ স্ট্রিংগুলিতে প্রথম শ্রেণির নাগরিক নয়। স্ট্রিং অপারেশনগুলি স্ট্যান্ডার্ড লাইব্রেরির মাধ্যমে করা হয়। আমার মনে হয়, এটাই কারণ। এছাড়াও, সি ++ স্যুইচ কেস স্টেটমেন্টগুলি অনুকূল করতে শাখা টেবিল অপ্টিমাইজেশন ব্যবহার করে। লিঙ্কটি দেখুন।

http://en.wikipedia.org/wiki/Switch_statement


2

সি ++ এ আপনি কেবল ইনট এবং চরটিতে একটি স্যুইচ স্টেটমেন্ট ব্যবহার করতে পারেন


3
একটি গৃহস্থালি এছাড়াও একটি ইনট মধ্যে পরিবর্তিত হয়।
স্টারগার

পয়েন্টারগুলিও পারে। এর অর্থ আপনি কখনও কখনও এমন কোনও কিছু সংকলন করতে পারেন যা কোনও ভিন্ন ভাষায় উপলব্ধি করতে পারে তবে এটি সঠিকভাবে চলবে না।
ডেভিড থর্নলি

আপনি আসলে ব্যবহার করতে পারেন longএবং long long, যা রূপান্তরিত হবে নাint । সেখানে কেটে যাওয়ার কোনও ঝুঁকি নেই।
এমসাল্টারস


0
    cout << "\nEnter word to select your choice\n"; 
    cout << "ex to exit program (0)\n";     
    cout << "m     to set month(1)\n";
    cout << "y     to set year(2)\n";
    cout << "rm     to return the month(4)\n";
    cout << "ry     to return year(5)\n";
    cout << "pc     to print the calendar for a month(6)\n";
    cout << "fdc      to print the first day of the month(1)\n";
    cin >> c;
    cout << endl;
    a = c.compare("ex") ?c.compare("m") ?c.compare("y") ? c.compare("rm")?c.compare("ry") ? c.compare("pc") ? c.compare("fdc") ? 7 : 6 :  5  : 4 : 3 : 2 : 1 : 0;
    switch (a)
    {
        case 0:
            return 1;

        case 1:                   ///m
        {
            cout << "enter month\n";
            cin >> c;
            cout << endl;
            myCalendar.setMonth(c);
            break;
        }
        case 2:
            cout << "Enter year(yyyy)\n";
            cin >> y;
            cout << endl;
            myCalendar.setYear(y);
            break;
        case 3:
             myCalendar.getMonth();
            break;
        case 4:
            myCalendar.getYear();
        case 5:
            cout << "Enter month and year\n";
            cin >> c >> y;
            cout << endl;
            myCalendar.almanaq(c,y);
            break;
        case 6:
            break;

    }

4
যদিও এই কোডটি প্রশ্নের উত্তর দিতে পারে, কেন এবং / অথবা এই কোডটির প্রশ্নের উত্তর কীভাবে তার দীর্ঘমেয়াদী মানকে উন্নত করে তা সম্পর্কিত অতিরিক্ত প্রসঙ্গ সরবরাহ করে ।
বেনিয়ামিন ডাব্লু।

0

অনেক ক্ষেত্রে আপনি স্ট্রিং থেকে প্রথম চরটি টেনে এনে স্যুইচ করে অতিরিক্ত কাজ করতে আগ্রহী হতে পারেন। যদি আপনার মামলাগুলি একই মান দিয়ে শুরু হয় তবে চ্যারেটে নেস্টেড সুইচটি করতে হবে (1)। আপনার কোড পড়া যে কেউ একটি ইঙ্গিত প্রশংসা করতে হবে যদিও বেশিরভাগ যদি ঠিক-অন্যথায় - যদি তা হবে


0

স্যুইচ সমস্যার আরও কার্যকরী কাজ:

class APIHandlerImpl
{

// define map of "cases"
std::map<string, std::function<void(server*, websocketpp::connection_hdl, string)>> in_events;

public:
    APIHandlerImpl()
    {
        // bind handler method in constructor
        in_events["/hello"] = std::bind(&APIHandlerImpl::handleHello, this, _1, _2, _3);
        in_events["/bye"] = std::bind(&APIHandlerImpl::handleBye, this, _1, _2, _3);
    }

    void onEvent(string event = "/hello", string data = "{}")
    {
        // execute event based on incomming event
        in_events[event](s, hdl, data);
    }

    void APIHandlerImpl::handleHello(server* s, websocketpp::connection_hdl hdl, string data)
    {
        // ...
    }

    void APIHandlerImpl::handleBye(server* s, websocketpp::connection_hdl hdl, string data)
    {
        // ...
    }
}

-1

আপনি স্যুইচ ক্ষেত্রে স্ট্রিং ব্যবহার করতে পারবেন না int কেবলমাত্র ইন্ট আর চর অনুমোদিত। পরিবর্তে আপনি স্ট্রিং উপস্থাপনের জন্য এনাম চেষ্টা করতে পারেন এবং এটি যেমন সুইচ কেস ব্লক ব্যবহার করতে পারেন

enum MyString(raj,taj,aaj);

এটি সুইচ কেস স্টেটমেন্টটি ব্যবহার করুন।



-1

স্যুইচগুলি কেবলমাত্র অবিচ্ছেদ্য ধরণের (ইন্ট, চর, বুল ইত্যাদি) সাথে কাজ করে। কোনও সংখ্যার সাথে একটি স্ট্রিং যুক্ত করতে এবং তারপরে স্যুইচটি দিয়ে সেই নম্বরটি ব্যবহার করতে মানচিত্রটি কেন ব্যবহার করবেন না?


-2

কারণ সি ++ স্যুইচগুলি জাম্প টেবিলগুলিতে পরিণত করে। এটি ইনপুট ডেটাতে একটি তুচ্ছ ক্রিয়াকলাপ সম্পাদন করে এবং তুলনা না করে সঠিক ঠিকানায় লাফ দেয়। যেহেতু স্ট্রিং একটি সংখ্যা নয়, তবে সংখ্যার একটি অ্যারে, সি ++ এটি থেকে জাম্প টেবিল তৈরি করতে পারে না।

movf    INDEX,W     ; move the index value into the W (working) register from memory
addwf   PCL,F       ; add it to the program counter. each PIC instruction is one byte
                    ; so there is no need to perform any multiplication. 
                    ; Most architectures will transform the index in some way before 
                    ; adding it to the program counter

table                   ; the branch table begins here with this label
    goto    index_zero  ; each of these goto instructions is an unconditional branch
    goto    index_one   ; of code
    goto    index_two
    goto    index_three

index_zero
    ; code is added here to perform whatever action is required when INDEX = zero
    return

index_one
...

(উইকিপিডিয়া থেকে কোড https://en.wikedia.org/wiki/Branch_table )


4
সি ++ এর সিনট্যাক্সের কোনও বিশেষ প্রয়োগের প্রয়োজন হয় না। একটি নিষ্পাপ cmp/ jccবাস্তবায়ন সি ++ স্ট্যান্ডার্ড অনুযায়ী ঠিক একই বৈধ হতে পারে।
রুসলান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.