2017-12-18 54 views
5

सी ++ में टेम्पलेट metaprogramming, मैं अक्सर निम्नलिखित की तरह कुछ में चलाते हैं:अंतर remove_reference

template <typename T> 
S<T> make_wrapper(T&& t) { return S<T>(std::forward<T>(t)); } 

मैं जानता हूँ कि मैं वापसी प्रकार में std::decay की तरह कुछ का उपयोग करना चाहिए, लेकिन std::remove_reference क्यों काम नहीं करेगा? यहाँ क्या अंतर है? std::remove_cvref के बारे में क्या?

+5

[क्षय बहुत कुछ कर सकता है] (http://en.cppreference.com/w/cpp/types/decay) 'टी' के आधार पर। –

+5

क्या आपने उनके बारे में पढ़ने की कोशिश की है? उदाहरण के लिए [यह 'std :: decay' संदर्भ] (http://en.cppreference.com/w/cpp/types/decay) और [यह' std :: remove_reference' संदर्भ] (http: //en.cppreference .com/डब्ल्यू/सीपीपी/प्रकार/remove_reference)। –

उत्तर

4

संदर्भ हटाने से const और volatile छोड़ दिया जाएगा। यदि आप यही चाहते हैं, तो यह पर्याप्त होगा।

सीवीआरई को हटाने से अधिकांश क्षय होता है, लेकिन फ़ंक्शन प्रकारों और सरणी प्रकारों को पॉइंटर्स में परिवर्तित नहीं करता है।

क्षय एक प्रकार को इस तरह से परिवर्तित करता है कि आप उचित रूप से किसी सरणी में या struct में इसकी प्रतिलिपि संग्रहीत कर सकते हैं, या इसे वापस कर सकते हैं या इसे किसी फ़ंक्शन में पास कर सकते हैं।

8

उदाहरण

#include <type_traits> 

int main() 
{ 
    static_assert(std::is_same_v< 
     std::decay_t<const int&>, 
     std::remove_reference_t<const int&> 
    >); // int != const int 
} 

std::decay के लिए विचार करें किसी भी सीवी-qualifer निकाल देंगे, remove_reference नहीं होगा। यह सिर्फ प्रकार के "संदर्भ" भाग को पट्टी कर देगा।

reference से:

लागू होता है lvalue करने वाली rvalue, सरणी-टू-सूचक, और समारोह करने के लिए सूचक प्रकार टी करने के लिए अंतर्निहित रूपांतरण, को हटा सीवी-क्वालिफायर, और को परिभाषित करता है जिसके परिणामस्वरूप सदस्य टाइपपीफ प्रकार के रूप में टाइप करें।

इसलिए std::decaystd::remove_reference से जिस तरह से अधिक प्रकार रूपांतरण प्रदर्शन करेंगे।

भी है कि केवल संभव परिवर्तनों decay करता है, remove_cv, remove_volatile तरह के सेट के कुछ हिस्सों का चयन किया प्रदर्शन के बारे में या, सी ++ 20, remove_cvref में अधिक सूक्ष्म अनुप्रयोगों के लिए आगे प्रकार संशोधक हैं।

+0

क्या 'std :: remove_cvref' पर्याप्त है? –

+1

@Nex ': नहीं। यह वास्तव में [docs] (http://en.cppreference.com/w/cpp/types/decay) पढ़ने में केवल 2 मिनट लगते हैं। –

+0

@Nex 'शायद आपको 'std :: invoke' के उपयोग पर विचार करना चाहिए। – Jodocus