मैं एक टेम्पलेट फ़ंक्शन लिखने की कोशिश कर रहा हूं जो केवल std::vector को तर्क के रूप में स्वीकार करेगा। हालाँकि जो मैं लेकर आया हूँ वह केवल सामान्य या लैवल्यू मापदंडों के लिए काम करता है, लेकिन संदर्भ तर्कों को अग्रेषित करने के लिए नहीं।

निम्नलिखित कोड संकलित नहीं करता है।

template <typename T, typename = typename std::enable_if< std::is_same<T, std::vector< typename T::value_type, typename T::allocator_type > >::value>::type >
int f(T && a) {
    return a.size();
}

int main() {
    std::vector<int> a;
    f(a);
}

हालांकि अगर मैं पैरामीटर प्रकार f को एक लाभा संदर्भ के रूप में प्रतिस्थापित करता हूं या मान प्रकार द्वारा पास करता हूं:

template <typename T, typename = typename std::enable_if< std::is_same<T, std::vector< typename T::value_type, typename T::allocator_type > >::value>::type >
int f(T a) {
    return a.size();
}

की तुलना में यह संकलित करता है।

ध्यान दें कि, मुझे एक अग्रेषण संदर्भ f का तर्क होना चाहिए।

मुझे किसकी याद आ रही है?

2
Ozgur Murat 11 नवम्बर 2019, 20:35

1 उत्तर

सबसे बढ़िया उत्तर

यदि आप केवल वैक्टर स्वीकार करना चाहते हैं, तो आपके कोड को काफी सरल बनाया जा सकता है। SFINAE का उपयोग करने के बजाय, आप बस निर्दिष्ट कर सकते हैं कि आप किसी भी प्रकार के पैरामीटर के साथ std::vector चाहते हैं। ऐसा दिखेगा

template <typename... Pack>
int f(std::vector<Pack...>const & a)
{
    return a.size();
}

आपके SFINAE दृष्टिकोण के काम न करने का कारण यह है कि जब आप फ़ंक्शन T के लिए एक लैवल्यू पास करते हैं तो उसे संदर्भ प्रकार के रूप में घटाया जाता है। जब चीजों को करने की बात आती है तो संदर्भ प्रकार स्वयं प्रकार की तरह काम नहीं करते हैं

typename T::value_type

इसे ठीक करने के लिए आपको std::remove_reference का उपयोग करके T की संदर्भ-नेस को हटाना होगा। यह आपको एक फंक्शन देगा जैसे

template <typename T, typename VecType = typename std::remove_reference<T>::type, typename = typename std::enable_if< std::is_same<VecType, std::vector< typename VecType::value_type, typename VecType::allocator_type > >::value>::type >
int f(T && a) {
    return a.size();
}
3
NathanOliver 11 नवम्बर 2019, 20:48