2011-12-20 11 views
10

मान लीजिए मैं दो struct रों है:बिल्कुल सही वस्तु के एक सदस्य अग्रेषण

struct X {}; 
struct Y { X x; } 

मैं कार्यों:

void f(X&); 
void f(X&&); 

मैं एक समारोह g() कि Y& या Y&& लेकिन सही अग्रेषण X& लेता है कैसे लिख सकता हूँ या X&& से f() क्रमश:

template <typename T> 
void g(T&& t) { 
    if (is_lvalue_reference<T>::value) { 
    f(t.x); 
    } else { 
    f(move(t.x)); 
    } 
} 

उपरोक्त कोड मेरे इरादे को चित्रित करता है लेकिन पैरामीटर की संख्या बढ़ने के साथ बहुत स्केलेबल नहीं है। क्या यह एक सही तरीका है कि इसे सही अग्रेषण के लिए काम करें और इसे स्केलेबल बनाएं?

+0

मैं 'is_lvalue_reference :: मान'' is_lvalue_reference के लिए बदल रहा लगता है कि :: (टी))> :: value' में आपके द्वारा इच्छित अर्थशास्त्र होगा, लेकिन मुझे लगता है कि आपकी वांछित अर्थशास्त्र संदिग्ध हैं ... – ildjarn

+0

(बॉट किए गए उत्तर के लिए खेद है।) मैं कहूंगा कि यह स्केल नहीं करता है क्योंकि डिज़ाइन है साथ शुरू करने के लिए संदिग्ध। उपरोक्त "स्थानांतरित" करने का क्या अर्थ है? यह किस राज्य में मुख्य वस्तु को छोड़ देता है? यहां तक ​​कि अगर इसे लिखने का एक आसान तरीका था, तो यह खराब संरचित कोड की तरह दिखता है ... –

उत्तर

15
template <typename T> 
void g(T&& t) { 
    f(std::forward<T>(t).x); 
} 
+1

मेरे लिए अच्छा लग रहा है http://ideone.com/Edf4o –

+0

बहुत अच्छा समाधान, लेकिन यह वास्तव में क्यों काम करता है? – Pubby

+0

@ पब्बी क्योंकि 'rvalue.foo' एक रैल्यू है। मैं सोच सकता हूं कि यह क्यों समझ सकता है (यदि कंटेनर का जीवनकाल कम रहता है और एक रावल है, निहित वस्तु भी उस संपत्ति को साझा करती है), लेकिन मैं दर्शन से परिचित नहीं हूं और तर्क को नहीं जानता, इसलिए मैं इसके बारे में कुछ भी नहीं कह सकता। –

3

मुझे लगता है कि यह काम करेगा, हालांकि मुझे यकीन नहीं है:

template<class T, class M> 
struct mforward { 
    using type = M&&; 
}; 
template<class T, class M> 
struct mforward<T&, M> { 
    using type = M&; 
}; 

template <typename T> 
void g(T&& t) { 
    f(std::forward<typename mforward<T, decltype(t.x)>::type>(t.x)); 
} 
+2

+1 मुझे libC++ में लगभग इस सटीक समस्या को हल करना पड़ा। जिस समाधान के साथ मैं आया था वह पब्बी के समान दिखता था। न केवल मैं 'टी' से' एम' की एल/आर-वैलेंटाइनेस "लागू" करना चाहता था, मैं भी 'टी' की सीवी-योग्यता' एम' पर लागू करना चाहता था। और मुझे डेटा सदस्यों के बाहर इसके लिए आवेदन मिले। उत्सुकता के लिए, मैंने इसे '__apply_cv' कहा और यह ओपन सोर्स कोड है: http://libcxx.llvm.org/ –

+0

@ हावर्ड एक विकल्प के लिए मेरा उत्तर देखें। या मुझे कुछ याद आती है? –

+0

इसके अलावा @ सीवा योग्यता के बारे में बात करते हुए हावर्ड ने मुझे इस जवाब की खामियों के बारे में सोचा है। 'decltype (t.x) 'केवल आपको घोषित प्रकार' x' देता है। यदि 'टी'' const' है, लेकिन 'x' को' int a' के रूप में घोषित किया गया था तो आपका आगे चीजों को 'int & '/' int && 'के रूप में अग्रेषित करने का प्रयास करेगा। आपको 'tyename remove_reference :: टाइप' जैसे कुछ भी कहने की आवश्यकता होगी ताकि' t' की स्थिरता भी ध्यान में रख सके। यह 'उत्परिवर्तनीय' सदस्यों को भी ध्यान में रखता है, लेकिन मुझे नहीं पता कि किस कदम का अर्थ अन्यथा 'कॉन्स्ट' ऑब्जेक्ट के एक परिवर्तनीय सदस्य को दार्शनिक रूप से करना है। –