2008-12-15 38 views
6

में मामलों के रूप में निरंतर सरणी के तत्वों का उपयोग करके मैं कमांड के सेट पर कुंजी प्रेस के सेट को मैप करने का प्रयास कर रहा हूं। चूंकि मैं कई स्थानों से कमांड को संसाधित करता हूं, इसलिए मैं कुंजी और कमांड के बीच अमूर्तता की एक परत स्थापित करना चाहता हूं ताकि अगर मैं अंतर्निहित कुंजी मैपिंग बदलूं, तो मुझे बहुत अधिक कोड बदलने की ज़रूरत नहीं है। मेरे वर्तमान प्रयास इस तरह दिखता है:स्विच स्टेटमेंट

// input.h 
enum LOGICAL_KEYS { 
    DO_SOMETHING_KEY, 
    DO_SOMETHING_ELSE_KEY, 
    ... 
    countof_LOGICAL_KEYS 
}; 

static const SDLKey LogicalMappings[countof_LOGICAL_KEYS] = { 
    SDLK_RETURN, // Do Something 
    SDLK_ESCAPE, // Do Something Else 
    ... 
}; 

// some_other_file.cpp 
... 
switch(event.key.keysym.key) { 
    case LogicalMappings[ DO_SOMETHING_KEY ]: 
     doSomething(); 
     break; 
    case LogicalMappings[ DO_SOMETHING_ELSE_KEY ]: 
     doSomethingElse(); 
     break; 
    ... 
} 

जब मैं इस (जीसीसी 4.3.2) संकलित करने के लिए मैं त्रुटि संदेश मिलता है कोशिश:

error: 'LogicalMappings' cannot appear in a constant-expression

मैं देख रहा हूँ क्यों नहीं संकलक एक समस्या है इसके साथ। मैं समझता हूं कि आपको केस स्टेटमेंट में चर होने की अनुमति क्यों नहीं है, लेकिन मैं इस धारणा के तहत था कि आप स्थिरांक का उपयोग कर सकते हैं, क्योंकि उनका संकलन समय पर मूल्यांकन किया जा सकता है। निरंतर सरणी स्विच स्टेटमेंट के साथ काम नहीं करते हैं? यदि ऐसा है, तो मुझे लगता है कि मैं सरणी को केवल कुछ के साथ बदल सकता हूं:

static const SDLKey LOGICAL_MAPPING_DO_SOMETHING  = SDLK_RETURN; 
static const SDLKey LOGICAL_MAPPING_DO_SOMETHING_ELSE = SDLK_ESCAPE; 
... 

लेकिन यह बहुत कम सुरुचिपूर्ण लगता है। क्या कोई जानता है कि आप यहां निरंतर सरणी का उपयोग क्यों नहीं कर सकते?

संपादित करें: मैंने सी ++ मानक का थोड़ा सा देखा है जो दावा करता है कि, "एक अभिन्न निरंतर अभिव्यक्ति में केवल शाब्दिक (2.13), एन्युमेटर, कॉन्स वैरिएबल या स्थिरांक के साथ शुरू किए गए अभिन्न या गणना प्रकारों के स्थिर डेटा सदस्य शामिल हो सकते हैं अभिव्यक्तियां (8.5) ... "। मैं अभी भी नहीं देखता कि क्यों एक स्थिर सरणी एक निरंतर अभिव्यक्ति के साथ शुरू की गई गणना प्रकार के रूप में नहीं गिना जाता है। यह हो सकता है कि मेरे प्रश्न का उत्तर "क्योंकि यह वही तरीका है," और मुझे इसके आसपास काम करना होगा। लेकिन अगर ऐसा है, तो यह निराशाजनक है, क्योंकि संकलक वास्तव में संकलित समय पर उन मानों को निर्धारित कर सकता है।

+0

"एक निरंतर अभिव्यक्ति के साथ प्रारंभिक गणना प्रकार" कुछ है "MyEnum a = 12", जहां MyEnum एक enum प्रकार है (यानी enum कीवर्ड के साथ घोषित/परिभाषित)। एक सरणी-enum प्रकार enum प्रकार के समान नहीं है कि यह एक सरणी है। –

उत्तर

0

क्या "लॉजिकल मैपिंग्स" के लिए एक तुलना ऑपरेटर परिभाषित किया गया है? यदि नहीं तो वह त्रुटि है।

+0

मुझे यकीन नहीं है कि मैं समझता हूं कि आपका क्या मतलब है ... क्या आप विस्तृत कर सकते हैं? –

+0

मैं क्या पूछना चाहता था कि क्लास लॉजिकल मैपिंग्स के लिए समानता ऑपरेटर ओवरलोड हो गया है। यह देखते हुए कि 'swicth' ब्लॉक 'केस' खोजने के लिए समानता ऑपरेटर का उपयोग करते हैं। –

1

मैं यहां एक अंग पर जाऊंगा क्योंकि किसी और ने इसका उत्तर नहीं दिया है और मैं हाल ही में जावा कर रहा हूं, सी ++ नहीं, लेकिन जहां तक ​​मुझे लगता है कि एक सरणी लुकअप को एक पूर्णांक पूर्णांक नहीं माना जाता है, भले ही लुकअप का परिणाम संकलन समय पर निर्धारित किया जा सकता है। यह वाक्यविन्यास में भी एक मुद्दा हो सकता है।

2

ऐरे संदर्भ "निरंतर पर्याप्त" नहीं हैं, भले ही।

आपको बस थोड़ा अलग मैपिंग करने की आवश्यकता है। आप लॉजिकल कुंजी दबाए जाने पर भी वही क्रिया करना चाहते हैं, इसलिए caseswitch कथन के खंडों में लॉजिकल कुंजी कोड का उपयोग करें। फिर लॉजिकल कोड पर वास्तविक कुंजी कोड को मानचित्र करें, संभवतः switch में, या संभवतः पहले से हाथ में। आप अभी भी LogicalMappings सरणी, या एक समान निर्माण का उपयोग कर सकते हैं। और, जी 11 एन (वैश्वीकरण) की सहायता के रूप में, आप मानचित्रण सरणी को निरंतर बना सकते हैं ताकि अलग-अलग लोग अपनी आवश्यकताओं के अनुरूप कुंजी को रीमेप कर सकें।

3

सी ++ मानक के अनुभागों का जिक्र करते हुए: 6.4.2 की आवश्यकता है कि केस एक्सप्रेशन एक अभिन्न या गणना निरंतर मूल्यांकन करें। 5.19 परिभाषित करता है कि क्या है:

An integral constant-expression can involve only literals (2.13), enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions (8.5), non-type template parameters of integral or enumeration types, and sizeof expressions. Floating literals (2.13.3) can appear only if they are cast to integral or enumeration types. Only type conversions to integral or enumeration types can be used. In particular, except in sizeof expressions, functions, class objects, pointers, or references shall not be used, and assignment, increment, decrement, function-call, or comma operators shall not be used.

तो अपने सवाल था अगर "क्यों संकलक अस्वीकार करता है यह", एक जवाब है, "मानक इसलिए कहते हैं क्योंकि"।

-1

LOGICAL_MAPPING_DO_SOMETHING = SDLK_RETURN जैसे कुछ समान मूल्य उत्पन्न करते हैं, इसलिए आपका मानचित्रण x-> x ऑपरेशन बन जाता है।

क्यों स्थिर स्थिरांक के किसी सदस्य या गणना स्थायी साथ टेम्पलेट वर्ग का उपयोग नहीं, कहते हैं, मूल्य, nessesary मानचित्रण विशेषज्ञता के साथ प्रदान करते हैं, और फिर आप

case LogicalMappings<DO_SOMETHING_KEY>::Value: ... 
+0

काम नहीं करता है ... –

0

लिख सकता है वहाँ एक पुस्तकालय बुलाया signal बढ़ावा में मदद करेगा यदि आप एक घटना मानचित्रण नहीं बना abstraction.If आप समय यह बेहतर दृष्टिकोण होना चाहिए

0

आप भी समारोह संकेत या functors (मैं functor पतों लगता है), की एक सरणी इस्तेमाल कर सकते हैं स्विच बयान पूरी तरह से बचने के लिए & सिर्फ सरणी सूचकांक से जाना -> फ़ंक्शन पॉइंटर/फ़ैक्टर्स direc tly।

(उदाहरण के लिए चेतावनी, अपरीक्षित कोड इस प्रकार)

class Event // you probably have this defined already 
{ 
} 

class EventHandler // abstract base class 
{ 
public: 
    virtual void operator()(Event& e) = 0; 
}; 

class EventHandler1 
{ 
    virtual void operator()(Event& e){ 
    // do something here 
    } 
}; 
class EventHandler2 
{ 
    virtual void operator()(Event& e){ 
    // do something here 
    } 
}; 

EventHandler1 ev1; 
EventHandler2 ev2; 
EventHandler *LogicalMappings[countof_LOGICAL_KEYS] = { 
    &ev1, 
    &ev2, 
    // more here... 

}; 

// time to use code: 
Event event; 
if (event.key.keysym.key < countof_LOGICAL_KEYS) 
{ 
    EventHandler *p = LogicalMappings[event.key.keysym.key]; 
    if (p != NULL) 
     (*p)(event); 
} 
0

काम पर एक संकलक गुरु मुझे यह समझाया। समस्या यह है कि सरणी स्वयं स्थिर है, लेकिन इसके लिए सूचकांक जरूरी नहीं हैं। इस प्रकार, अभिव्यक्ति LogicalMappings [some_variable] का संकलन समय पर मूल्यांकन नहीं किया जा सका, इसलिए सरणी संकलित होने के बजाए स्मृति में संग्रहीत की जा रही है। अभी भी कोई कारण नहीं है कि संकलक स्थिर रूप से किसी कॉन्स या शाब्दिक सूचकांक के साथ सरणी संदर्भों का मूल्यांकन नहीं कर सका, इसलिए मैं सैद्धांतिक रूप से संभव होना चाहिए, लेकिन यह सोचने की तुलना में थोड़ा सा कठिन है, इसलिए मैं समझ सकता हूं कि जीसीसी क्यों नहीं यह मत करो।

संबंधित मुद्दे