मैं रचना का उपयोग करना चाहता हूं और सी ++ क्षमताओं का उपयोग करके प्रत्येक संभावित ओवरलोड (नोएसेप्ट, कॉन्स, अस्थिर) के लिए अच्छी अग्रेषण विधियों को लिखना चाहता हूं।विरासत की बजाय संरचना के साथ विधि अग्रेषण (सी ++ लक्षणों का उपयोग करके)
विचार यह निर्धारित करने के लिए गुणों का उपयोग करना है कि कोई तरीका घोषित किया गया है {noexcept/const/volatile/etc} और तदनुसार व्यवहार करना है।
यहाँ मैं प्राप्त करना चाहते हैं का एक उदाहरण है:
// forward with noexcept attribute
// I'm not 100% sure about : std::declval<std::add_lvalue_reference<decltype(obj)>::type
template<typename... Args>
constexpr decltype(auto) get(Args && ... args)
noexcept(
noexcept(std::declval<std::add_lvalue_reference<decltype(obj)>::type>().get( std::forward<Args>(args)... ))
and
std::is_nothrow_move_constructible<decltype(std::declval<std::add_lvalue_reference<decltype(obj)>::type>().get( std::forward<Args>(args)... ))>::value
)
{
cout << "const called...\n";
return obj.get(std::forward<Args>(args)...);
}
// forward with noexcept and const attributes
// I'm not sure that this one behave properly.
template<typename... Args>
constexpr decltype(auto) get(Args && ... args)
const noexcept(
noexcept(std::declval< std::add_const<decltype(obj) &>::type >().get( std::forward<Args>(args)... ))
and
std::is_nothrow_move_constructible<decltype(std::declval< std::add_const<decltype(obj) &>::type >().get( std::forward<Args>(args)... ))>::value
)
{
cout << "const not called...\n";
using const_type = std::add_lvalue_reference<std::add_const<std::remove_reference<decltype(obj)>::type>::type>::type;
return const_cast<const_type>(obj).get(std::forward<Args>(args)...);
}
कृपया ध्यान दें कि इस प्रश्न का अनुसरण से अलग है:
struct User{
UsedObject& obj;
User(UsedObject& obj) : obj(obj) {}
FORWARD_METHOD(obj, get); //here is where the forwarding happens
};
struct UsedObject{
string m{"Hello\n"};
string& get(double d){
cout << "\tUsed :const not called...\n";
return m;
}
const string& get(double d) const{
cout << "\tUsed :const called...\n";
return m;
}
};
यहाँ मैं क्या अब तक ** है एक, क्योंकि मुझे पता है कि हम ऑब्जेक्ट इंटरफेस का निरीक्षण करने के लिए सी ++ लक्षणों का उपयोग कर सकते हैं: Composition: using traits to avoid forwarding functions?
** @ डेविड एस के साथ टिप्पणियों के धागे से प्रेरित यहां टोन: When should I use C++ private inheritance?।
आपके बहुत अच्छे उत्तर के लिए धन्यवाद! मैंने मेटा प्रोग्रामिंग के बारे में बहुत कुछ सीखा। क्या हम इसे इस तरह इस्तेमाल कर सकते हैं? 'FORWARDING_MEMBER_FUNCTIONS (std :: decay :: प्रकार, आंतरिक, फ़ंक्शन)' और सदस्य सूचक के साथ: 'FORWARDING_MEMBER_FUNCTIONS (std :: decay :: type, * ptr , फ़ंक्शन); ' ? –
बीटीडब्लू, सी ++ को समान वाक्यविन्यास 'आंतरिक उपयोग करने के लिए' का उपयोग करने से रोकता है; संरचना के लिए? –
@ जुलिएन__ आप पैरामीटर के प्रकार को स्वीकार करने के लिए मैक्रो बदल सकते हैं। नकारात्मकता यह है कि आपके पास FORWARDING_MEMBER_FUNCTIONS को आमंत्रित करने से पहले आपकी परिवर्तनीय घोषणा होनी चाहिए, जबकि यदि आप स्पष्ट रूप से प्रकार निर्दिष्ट करते हैं, तो वह प्रतिबंध मौजूद नहीं है। जो आपके लिए बेहतर है आप पर निर्भर है। संदर्भ क्वालीफायर के कारण, शायद आप पॉइंटर्स के साथ इसका उपयोग नहीं करना चाहेंगे। सी ++ सदस्यों के कार्यों के लिए आगे बढ़ने के लिए उपयोग वाक्यविन्यास का उपयोग करने से रोकता है, सिवाय इसके कि आपको समिति को इसे स्वीकार करने के लिए मनाने की आवश्यकता होगी। –