स्विच स्टेटमेंट को स्ट्रिंग्स पर क्यों नहीं लागू किया जा सकता है?


227

निम्नलिखित कोड संकलित किया गया और त्रुटि मिली type illegal

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

आप switchया तो स्ट्रिंग का उपयोग नहीं कर सकते हैं या case। क्यों? क्या कोई समाधान है जो स्ट्रिंग पर स्विच करने के लिए तर्क का समर्थन करने के लिए अच्छी तरह से काम करता है?


6
क्या एक बढ़ावा विकल्प है जो नक्शा निर्माण को छुपाता है, एक मैक्रो के पीछे रहता है?
बाल्की

@ बाल्की मैं बढ़ावा के बारे में निश्चित नहीं हूं लेकिन इस तरह के मैक्रोज़ लिखना आसान है। Qt के मामले में, आप मैपिंग को छुपा सकते हैंQMetaEnum
phuclv

जवाबों:


189

कारण क्यों प्रकार प्रणाली के साथ क्या करना है। C / C ++ वास्तव में एक प्रकार के रूप में तार का समर्थन नहीं करता है। यह एक निरंतर चार सरणी के विचार का समर्थन करता है लेकिन यह वास्तव में एक स्ट्रिंग की धारणा को पूरी तरह से नहीं समझता है।

एक स्विच स्टेटमेंट के लिए कोड उत्पन्न करने के लिए कंपाइलर को यह समझना चाहिए कि दो मूल्यों के बराबर होने का क्या मतलब है। Ints और enums जैसी वस्तुओं के लिए, यह एक तुच्छ सा तुलना है। लेकिन कंपाइलर को 2 स्ट्रिंग मान की तुलना कैसे करनी चाहिए? केस सेंसिटिव, असंवेदनशील, कल्चर अवेयर, आदि ... स्ट्रिंग की पूरी जानकारी के बिना इसका सटीक उत्तर नहीं दिया जा सकता।

इसके अतिरिक्त, C / C ++ स्विच स्टेटमेंट आमतौर पर ब्रांच टेबल के रूप में उत्पन्न होते हैं । स्ट्रिंग स्टाइल स्विच के लिए शाखा तालिका बनाना लगभग आसान नहीं है।


11
शाखा तालिका तर्क लागू नहीं होना चाहिए - यह केवल एक संभव दृष्टिकोण है जो एक संकलक लेखक के लिए उपलब्ध है। एक उत्पादन संकलक के लिए, किसी को अक्सर स्विच की जटिलता के आधार पर कई दृष्टिकोणों का उपयोग करना पड़ता है।
कुर्सी

5
@plinth, मैंने इसे ज्यादातर ऐतिहासिक कारणों से रखा है। बहुत सारे "C / C ++ ऐसा क्यों करता है" सवालों का जवाब आसानी से संकलक के इतिहास द्वारा दिया जा सकता है। जिस समय उन्होंने इसे लिखा था, सी को महिमा मंडित किया गया था और इसलिए स्विच वास्तव में एक सुविधाजनक शाखा तालिका थी।
जारेडपर

113
मैं नीचे वोट देता हूं क्योंकि मुझे समझ में नहीं आता है कि कंपाइलर कैसे जानता है कि अगर बयानों में 2 स्ट्रिंग मानों की तुलना की जाए लेकिन स्विच स्टेटमेंट में एक ही काम करने के तरीके को भूल जाएं।

15
मुझे नहीं लगता कि पहले 2 पैराग्राफ वैध कारण हैं। विशेष रूप से सी ++ 14 के बाद से जब std::stringशाब्दिक रूप से जोड़े गए थे। यह ज्यादातर ऐतिहासिक है। लेकिन एक समस्या मन में आता है कि इस तरह से साथ है switchवर्तमान में काम करता है, नकल caseरों चाहिए संकलन समय पर पता लगाया जा; हालाँकि यह स्ट्रिंग्स के लिए इतना आसान नहीं होगा (रन-टाइम लोकल सेलेक्शन वगैरह को देखते हुए)। मुझे लगता है कि इस तरह की चीज़ों के लिए constexprमामलों की आवश्यकता होगी , या अनिर्दिष्ट व्यवहार में जोड़ना होगा (ऐसी चीज़ जो हम करना चाहते हैं)।
MM

8
दो std::stringमानों की तुलना करने की एक स्पष्ट परिभाषा है या यहां तक ​​कि std::stringएक कास्ट चार सरणी (ऑपरेटर == का उपयोग करके) के साथ कोई भी तकनीकी कारण नहीं है जो कंपाइलर को उस ऑपरेटर को प्रदान करने वाले किसी भी प्रकार के लिए स्विच स्टेटमेंट बनाने से रोक सके। यह जीवन भर की वस्तुओं जैसे कुछ प्रश्नों के बारे में बताता है लेकिन यह सब मुख्य रूप से एक भाषा डिजाइन निर्णय है, न कि तकनीकी कठिनाई।
माइक एमबी

60

जैसा कि पहले उल्लेख किया गया है, कंपाइलर लुकअप टेबल बनाना पसंद करते हैं जो switchजब भी संभव हो ओ (1) टाइमिंग के पास स्टेटमेंट को ऑप्टिमाइज़ करते हैं। इस तथ्य के साथ संयोजित करें कि C ++ भाषा में एक स्ट्रिंग प्रकार नहीं है - std::stringमानक लाइब्रेरी का हिस्सा है जो भाषा प्रति se का हिस्सा नहीं है।

मैं एक विकल्प पेश करूंगा, जिस पर आप विचार करना चाहते हैं, मैंने इसका उपयोग अच्छे प्रभाव के लिए किया है। स्ट्रिंग पर स्विच करने के बजाय, हैश फ़ंक्शन के परिणाम पर स्विच करें जो स्ट्रिंग को इनपुट के रूप में उपयोग करता है। यदि आप स्ट्रिंग के एक पूर्व निर्धारित सेट का उपयोग कर रहे हैं तो आपका कोड स्ट्रिंग पर स्विच करने के रूप में लगभग स्पष्ट होगा:

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
यह वास्तव में निराशाजनक है क्योंकि आप वास्तव में हैशिंग नहीं हैं। आधुनिक सी ++ के साथ आप वास्तव में एक कॉन्स्टैक्स हैश फ़ंक्शन का उपयोग करके संकलन समय पर हैश कर सकते हैं। आपका समाधान साफ ​​दिखता है लेकिन दुर्भाग्य से अगर सीढ़ी चल रही है तो यह सब बुरा है। नीचे दिए गए मानचित्र समाधान बेहतर होंगे और फ़ंक्शन कॉल से भी बचेंगे। इसके अतिरिक्त दो मानचित्रों का उपयोग करके आप त्रुटि लॉगिंग के लिए पाठ में बना सकते हैं।
डिर्क बेस्टर


क्या हैशटैग एक बाधा कार्य हो सकता है? यह देखते हुए कि आप एक std :: string के बजाय एक const char * में पास होते हैं।
विक्टर स्टोन

पर क्यों? यदि आप किसी स्विच के शीर्ष पर स्टेटमेंट निष्पादन के सभी समय का उपयोग करते हैं। दोनों का कम से कम प्रभाव पड़ता है, लेकिन एक स्विच के साथ प्रदर्शन लाभ इफ-लुकिंग द्वारा मिटा दिए जाते हैं। बस एक का उपयोग करते हुए और अधिक तेजी से होना चाहिए, लेकिन इससे भी महत्वपूर्ण, काफी छोटा।
झोए

20

सी ++

constexpr हैश फ़ंक्शन:

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
आपको यह सुनिश्चित करना होगा कि आपके किसी भी मामले में समान मान नहीं है। और फिर भी, आपकी कुछ गलतियाँ हो सकती हैं, जहाँ अन्य तार जो हैश के लिए होते हैं, उदाहरण के लिए, हैश ("एक") के समान मान गलत रूप से आपके स्विच में पहला "कुछ" करेंगे।
डेविड लजंग मैडिसन स्टेलर

मुझे पता है, लेकिन अगर यह समान मूल्य के लिए राख है तो यह संकलन नहीं करेगा और आप इसे समय पर नोटिस करेंगे।
निक

अच्छा बिंदु - लेकिन वह अन्य स्ट्रिंग्स के लिए हैश टकराव को हल नहीं करता है जो आपके स्विच का हिस्सा नहीं हैं। कुछ मामलों में जो मायने नहीं रखते हैं, लेकिन अगर यह एक सामान्य "गो-टू" समाधान था, तो मैं सोच सकता था कि यह एक सुरक्षा मुद्दा या कुछ बिंदु पर पसंद है।
डेविड लजंग मैडिसन स्टेलर

7
आप एक जोड़ सकते हैं operator "" कोड को और अधिक सुंदर बनाने के लिए । constexpr inline unsigned int operator "" _(char const * p, size_t) { return hash(p); }और इसका उपयोग case "Peter"_: break; डेमो की
hare1039

15

C ++ 11 के ऊपर जाहिरा तौर पर @MarmouCorp का अपडेट नहीं, लेकिन http://www.codeguru.com/cpp/cpp/cpp_mfc/article.php/c4067/Switch-on-Strings-in-C.htm

स्ट्रिंग्स और क्लास एनम (प्लेन एनम की तुलना में बेहतर) के बीच में बदलने के लिए दो मैप्स का उपयोग करता है क्योंकि इसके मान इसके अंदर स्कूप किए जाते हैं, और अच्छी त्रुटि संदेशों के लिए रिवर्स लुकअप)।

कोडगुरु कोड में स्टेटिक का उपयोग इनिशियल लिस्ट के लिए संकलक समर्थन के साथ संभव है जिसका अर्थ है वीएस 2013 प्लस। gcc 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]);
}

मुझे ध्यान देना चाहिए कि मुझे बाद में स्ट्रिंग शाब्दिकों की आवश्यकता होती है और समय गणना (C ++ 14 या 17 मुझे लगता है) का एक समाधान मिला, जहां आप संकलित समय पर केस स्ट्रिंग और हैश रनटाइम पर स्विच स्ट्रिंग कर सकते हैं। यह वास्तव में लंबे स्विच के लिए सार्थक होगा, लेकिन निश्चित रूप से कम बैकवर्ड संगत अगर वह मायने रखता है।
डिर्क बेस्टर

क्या आप संकलन-समय के समाधान को यहाँ साझा कर सकते हैं? धन्यवाद!
१३:०६ पर

12

समस्या यह है कि अनुकूलन के कारणों के लिए C ++ में स्विच स्टेटमेंट कुछ भी काम नहीं करता है लेकिन आदिम प्रकार, और आप केवल संकलन समय स्थिरांक के साथ उनकी तुलना कर सकते हैं।

संभवत: प्रतिबंध का कारण यह है कि कंपाइलर कोड को एक सीएमपी इंस्ट्रक्शन और एक गोटो के अनुरूप संकलन के कुछ प्रकार को लागू करने में सक्षम है, जहां रनटाइम पर तर्क के मूल्य के आधार पर पते की गणना की जाती है। चूंकि ब्रांचिंग और लूप आधुनिक सीपीयू के साथ अच्छी तरह से नहीं खेलते हैं, यह एक महत्वपूर्ण अनुकूलन हो सकता है।

इसके चारों ओर जाने के लिए, मुझे डर है कि आपको बयानों का सहारा लेना पड़ेगा।


स्विच स्टेटमेंट का एक अनुकूलित संस्करण जो स्ट्रिंग्स के साथ काम कर सकता है वह निश्चित रूप से संभव है। तथ्य यह है कि वे उसी प्रकार के कोड पथ का पुन: उपयोग नहीं कर सकते हैं जो वे आदिम प्रकारों के लिए उपयोग करते हैं इसका मतलब यह नहीं है कि वे std::stringभाषा में दूसरों को पहला नागरिक नहीं बना सकते हैं और एक कुशल एल्गोरिदम के साथ स्विच स्टेटमेंट में उनका समर्थन कर सकते हैं।
सीईसीटीको

10

std::map + सी + + 11 लैम्ब्डा पैटर्न एनम के बिना

unordered_mapसंभावित परिशोधन के लिए O(1): C ++ में HashMap का उपयोग करने का सबसे अच्छा तरीका क्या है?

#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विधि चर के आरंभ के साथ दूर हो सकते हैं : वर्ग विधियों में स्थैतिक चर , लेकिन हम यहां वर्णित विधियों का भी उपयोग कर सकते हैं: C ++ में स्थिर निर्माणकर्ता? मुझे निजी स्थिर वस्तुओं को इनिशियलाइज़ करने की आवश्यकता है

लंबर संदर्भ कैप्चर [&]को एक तर्क में बदलना आवश्यक था , या जो अपरिभाषित था: संदर्भ द्वारा कैप्चर के साथ उपयोग किए जाने वाले स्थिर स्थिर ऑटो लैम्ब्डा

उदाहरण जो ऊपर के समान आउटपुट का उत्पादन करता है:

#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

C ++ और C स्विच में केवल पूर्णांक प्रकारों पर काम करते हैं। इसके बजाय अगर सीढ़ी का उपयोग करें। सी ++ स्पष्ट रूप से स्ट्रिंग्स के लिए किसी प्रकार के swich स्टेटमेंट को लागू कर सकता था - मुझे लगता है कि किसी ने भी इसे सार्थक नहीं समझा, और मैं उनसे सहमत हूं।


सहमत हैं, लेकिन क्या आप जानते हैं कि इसका उपयोग संभव नहीं है
यशराज

इतिहास? वास्तविक संख्या, पॉइंटर्स और स्ट्रक्चर्स (C के केवल अन्य डेटा प्रकार) पर स्विच करने से संन्यास नहीं होता है, इसलिए C ने इसे पूर्णांक तक सीमित कर दिया है।

खासकर यदि आप उन कक्षाओं पर स्विच करते हैं जो अंतर्निहित रूपांतरणों की अनुमति देते हैं तो आपके पास एक बार वास्तव में अच्छा समय होगा।
शार्पटेल

6

क्यों नहीं? आप बराबर सिंटैक्स और समान शब्दार्थ के साथ स्विच कार्यान्वयन का उपयोग कर सकते हैं । Cभाषा सब पर वस्तुओं और तार वस्तुओं नहीं है, लेकिन में तार Cहै अशक्त समाप्त सूचक द्वारा संदर्भित तार। C++भाषा वस्तुओं तुलना या वस्तुओं समानताओं की जाँच के लिए अधिभार कार्यों बनाने के लिए संभावना है। जैसा Cकि भाषा के लिए और किसी भी प्रकार की वस्तुओं के लिए C++इस तरह के स्विच के लिए पर्याप्त लचीला है जो Cभाषा के लिए तुलना या चेक समानता का समर्थन करते 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या किसी भी संरचना या वर्गों के लिए अधिक जटिल प्रकारों का उपयोग करना संभव है जो समानता के संचालन (या त्वरित के लिए comarisions) का समर्थन करते हैं मोड के ) का समर्थन करते हैं।

विशेषताएं

  • किसी भी प्रकार का डेटा जो तुलना का समर्थन करता है या समानता की जाँच करता है
  • संभावना नेस्टेड स्विच स्टेटमेन्स के निर्माण की संभावना है।
  • मामला बयानों के माध्यम से टूटने या गिरने की संभावना
  • नॉन कॉन्स्टेंट केस एक्सप्रेशन का उपयोग करने की संभावना
  • पेड़ खोज के साथ त्वरित स्थिर / गतिशील मोड को सक्षम करने के लिए संभव है (C ++ 11 के लिए)

भाषा स्विच के साथ सिंटैक्स अंतर है

  • अपरकेस कीवर्ड
  • CASE स्टेटमेंट के लिए कोष्ठक की आवश्यकता है
  • अर्धविराम ''; बयानों के अंत में अनुमति नहीं है
  • बृहदान्त्र ':' पर ​​CASE कथन की अनुमति नहीं है
  • CASE स्टेटमेंट के अंत में BREAK या FALL कीवर्ड में से एक की जरूरत है

C++97भाषा के लिए रैखिक खोज का उपयोग किया। के लिए C++11और अधिक आधुनिक संभव quickमोड wuth पेड़ खोज का उपयोग करें जहां CASE में वापसी कथन की अनुमति नहीं है। 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

C ++ में स्ट्रिंग्स प्रथम श्रेणी के नागरिक नहीं हैं। स्ट्रिंग संचालन मानक पुस्तकालय के माध्यम से किया जाता है। मुझे लगता है, यही कारण है। साथ ही, C ++ स्विच केस स्टेटमेंट को ऑप्टिमाइज़ करने के लिए ब्रांच टेबल ऑप्टिमाइज़ेशन का उपयोग करता है। लिंक पर एक नजर है।

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


2

C ++ में आप केवल int और char पर एक स्विच स्टेटमेंट का उपयोग कर सकते हैं


3
एक चार इंट में भी बदल जाता है।
स्ट्रैजर

संकेत भी कर सकते हैं। इसका मतलब है कि आप कभी-कभी कुछ ऐसा संकलन कर सकते हैं जो एक अलग भाषा में समझ में आता है, लेकिन यह सही नहीं चलेगा।
डेविड थॉर्नले

आप वास्तव में उपयोग कर सकते हैं longऔर long long, जो चालू नहीं होगाint । वहां ट्रंकेशन का कोई खतरा नहीं है।
MSalters

यह उत्तर तथ्यात्मक रूप से गलत है। आप अभिन्न या गणन प्रकार की किसी भी अभिव्यक्ति का
rsjaffe

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 और char की अनुमति है। इसके बजाय आप स्ट्रिंग का प्रतिनिधित्व करने के लिए एनम की कोशिश कर सकते हैं और इसे स्विच केस ब्लॉक में उपयोग कर सकते हैं जैसे

enum MyString(raj,taj,aaj);

यह swich केस स्टेटमेंट का उपयोग करें।


यह उत्तर तथ्यात्मक रूप से गलत है। आप अभिन्न या गणन प्रकार की किसी भी अभिव्यक्ति का
rsjaffe

-1

स्विच केवल अभिन्न प्रकार (इंट, चार, बूल, आदि) के साथ काम करते हैं। किसी नंबर के साथ स्ट्रिंग को जोड़ने के लिए मैप का उपयोग क्यों नहीं किया जाता है और फिर स्विच के साथ उस नंबर का उपयोग किया जाता है?


-2

ऐसा इसलिए है क्योंकि C ++ जंप टेबल में स्विच बदल जाता है। यह इनपुट डेटा पर एक तुच्छ ऑपरेशन करता है और तुलना किए बिना उचित पते पर कूदता है। चूंकि एक स्ट्रिंग एक संख्या नहीं है, लेकिन संख्याओं की एक सरणी, C ++ इससे कूद तालिका नहीं बना सकती है।

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
...

(wikipedia से कोड https://en.wikipedia.org/wiki/Branch_table )


4
C ++ को इसके सिंटैक्स के किसी विशेष कार्यान्वयन की आवश्यकता नहीं है। एक भोली cmp/ jccकार्यान्वयन C ++ मानक के अनुसार ही मान्य हो सकता है।
रुस्लान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.