2015-09-21 12 views
5

का उपयोग कर फ़ंक्शन पैरामीटर प्रकार नोट: इस प्रश्न में प्रदान किया गया उदाहरण उत्पादन कोड नहीं है और इसका कोई मतलब नहीं है। यह मेरी समस्या का वर्णन करने के लिए बस है।decltype

मैं decltype की संभावनाओं का परीक्षण किया गया था, विशेष रूप से अगर यह समारोह पैरामीटर प्रकार अनुमान करते थे, और कोई समस्या हुई थी जाता है:

struct ClassInt 
{ 
    // Note: no default ctor 
    ClassInt(int value) 
     : m_Value(value) 
    {} 

    int m_Value; 
}; 

struct ClassDouble 
{ 
    // Note: no default ctor 
    ClassDouble(double value) 
     : m_Value(value) 
    {} 

    double m_Value; 
}; 

: दो वर्गों इस तरह संरचित

मान लीजिए वहाँ थे अब, मैंने एक फ़ंक्शन लिखा है कि (किसी भी तरह) स्ट्रिंग द्वारा टाइप पैरामीटर (जो ऊपर में से एक होना चाहिए) का एक उदाहरण पुनर्प्राप्त करता है और उसके m_Value सदस्य को दिए गए मान को असाइन करता है:

template< typename Ty > 
Ty* get_fake_ptr() { return nullptr; } 


// Retrieve pointer to Ty object by name and assign its value member. 
// The problem is that we don't actually have an instance of Ty at the point 
// where we want to define the type of the parameter "value". 
template< typename Ty > 
void assign(std::string name, decltype(get_fake_ptr<Ty>()->m_Value) value) 
{ 
    // Somehow get pointer to a Ty object by name 
    Ty* obj = ????; 

    // Assign 
    obj->m_Value = value; 
} 

अब पैरामीटर value का प्रकार टाइप पैरामीटर पर निर्भर है, क्योंकि उपयोग की गई कक्षा m_Value सदस्य के प्रकार में भिन्न होती है। जैसा कि आप देख सकते हैं, मैंने इसे decltype का उपयोग कर हल किया। अब, सामान्य रूप से, आप decltype एक पैरामीटर पर प्रयोग करेंगे, इस तरह:

template<typename Ty> 
void assign(Ty& obj, decltype(obj.m_Value) value); 

लेकिन वह स्पष्ट रूप से यहाँ संभव के बाद से वास्तविक उदाहरण समारोह शरीर में लिया गया है नहीं है और इस प्रकार बिंदु है जहां समारोह तर्क पर उपलब्ध नहीं है घोषित कर रहे हैं

मैंने टेम्पलेट फ़ंक्शन get_fake_ptr का उपयोग करके इसे एक साथ हैक किया है जो मिलान प्रकार के nullptr को लौटाता है, इसलिए मेरे पास "छद्म उदाहरण" है जो संकलक सदस्य प्रकार निर्धारित करने के लिए उपयोग कर सकता है। और यह काम करता है:

working

अब, जैसा कि मैंने कहा, यह वास्तव में hacky मुझे लगता है। तो:

क्या इस समस्या को हल करने का कोई बेहतर तरीका है?

धन्यवाद!

+2

आप अपने 'get_fake_ptr() 'फ़ंक्शन का उपयोग करने के बजाय टी के m_Value सदस्य के प्रकार को कम करने के लिए' decltype (std :: declval () .m_Value) का उपयोग कर सकते हैं। वे अंत में समान लक्ष्यों को पूरा करते हैं, मुझे लगता है। –

+1

वैसे, आपके 'get_fake_ptr() 'फ़ंक्शन को परिभाषित करने की आवश्यकता नहीं है। आप इसे 'टेम्पलेट टी * get_fake_ptr(); के रूप में छोड़ सकते हैं; और आप अभी भी इसे' decltype' के अंदर उपयोग कर सकते हैं। –

+1

'decltype (Ty :: m_value) 'के साथ क्या गलत है? – Casey

उत्तर

3

आप decltype(std::declval<T>().m_Value) का उपयोग T के m_Value बजाय सदस्य अपने get_fake_ptr() समारोह का उपयोग कर के प्रकार के अनुमान कर सकते हैं। वे अंत में समान लक्ष्यों को पूरा करते हैं।

वैसे, आपके get_fake_ptr() फ़ंक्शन को परिभाषित करने की आवश्यकता नहीं है। आप इसे template <typename T> T* get_fake_ptr(); के रूप में छोड़ सकते हैं और आप अभी भी decltype के अंदर इसका उपयोग कर सकते हैं।

3

मुझे इस दृष्टिकोण के साथ कुछ भी गलत नहीं लगता है।

जब टेम्पलेट मेटा-प्रोग्रामिंग की बात आती है, तो इस तरह के "हैक" पाठ्यक्रम के लिए समान हैं।

हालांकि, मैं थोड़ा अलग डिज़ाइन पैटर्न सुझा सकता हूं। इस तरह कुछ:

struct ClassInt 
{ 
    // Note: no default ctor 
    ClassInt(int value) 
     : m_Value(value) 
    {} 

    typedef int m_value_t; 

    m_value_t m_Value; 
}; 

struct ClassDouble 
{ 
    // Note: no default ctor 
    ClassDouble(double value) 
     : m_Value(value) 
    {} 

    typedef double m_value_t; 

    m_value_t m_Value; 
}; 

// ... 
template< typename Ty > 
void assign(std::string name, typename Ty::value_t value) 
{ 
    // Somehow get pointer to a Ty object by name 
    Ty* obj = ????; 

    // Assign 
    obj->m_Value = value; 
} 
2

एक और विकल्प एक और टेम्पलेट पैरामीटर जोड़ने और बस असाइनमेंट मिलान मिलान प्रकारों और रूपांतरणों को संभालने का है। कोई भी गैर परिवर्तनीय मान प्रकार संकलन त्रुटि उत्पन्न करेगा।

template<typename Ty, typename VALUE_TYPE> 
void assign(std::string name, VALUE_TYPE value) { 
    Ty* obj = ??? 
    obj->m_Value = value; 
} 
संबंधित मुद्दे