2011-01-28 5 views
9

मैं वर्तमान में ट्यूपल्स के लिए अंकगणितीय ऑपरेटर ओवरलोड लिखने की प्रक्रिया में हूं। ऑपरेटर अपने प्रत्येक व्यक्तिगत तत्व पर ऑपरेशन करने के लिए ट्यूपल पर फिर से चलाता है। यहाँ ऑपरेटर के लिए परिभाषा है + =:सी ++ - प्रकार बनाम स्थिर पैरामीटर के एक ट्यूपल और रिज़ॉल्यूशन पर इटरेटिंग

template< typename... Ts, std::size_t I = 0 > 
inline typename std::enable_if< I == sizeof... (Ts), std::tuple<Ts...>& >::type operator +=(std::tuple<Ts...>& lhs, const std::tuple<Ts...>& rhs) 
{ 
    return lhs; 
} 

template< typename... Ts, std::size_t I = 0 > 
inline typename std::enable_if< I != sizeof... (Ts), std::tuple<Ts...>& >::type operator +=(std::tuple<Ts...>& lhs, const std::tuple<Ts...>& rhs) 
{ 
    std::get<I>(lhs) += std::get<I>(rhs); 
    return operator +=< Ts..., I + 1 >(lhs, rhs); 
} 

दुर्भाग्य से, जब मैं ऑपरेटर कॉल करने का प्रयास, जीसीसी 4.6 तय नहीं कर सकता जो ओवरलोड इसका इस्तेमाल करना चाहिए। उदाहरण के लिए:

:/Workspace/raster/main.cpp:833:7: instantiated from here 
C:/Workspace/raster/main.cpp:809:45: error: no matching function for call to 'operator+=(std::tuple<int, int, int, int>&, const std::tuple<int, int, int, int>&)' 
C:/Workspace/raster/main.cpp:809:45: note: candidates are: 
C:/Workspace/raster/main.cpp:800:151: note: template<class ... Ts, unsigned int I> typename std::enable_if<(I == sizeof (Ts ...)), std::tuple<_TElements ...>&>::type operator+=(std::tuple<_TElements ...>&, const std::tuple<_TElements ...>&) 
C:/Workspace/raster/main.cpp:806:83: note: template<class ... Ts, unsigned int I> typename std::enable_if<(I != sizeof (Ts ...)), std::tuple<_TElements ...>&>::type operator+=(std::tuple<_TElements ...>&, const std::tuple<_TElements ...>&) 

कौन सा अजीब बात है के बाद से std::enable_if हालत अनुचित कॉल को अस्वीकार करना चाहिए:

std::tuple< int, int, int, int > a = std::make_tuple(1, 2, 3, 4), b = std::make_tuple(5, 6, 7, 8); 
a += b; 

निम्न त्रुटि अर्जित करता है। अभी के लिए, मेरे पास निम्नलिखित कार्यवाही है जो वास्तव में मेरा पूर्व कार्यान्वयन था। उपर्युक्त संस्करण वास्तव में एक सरलीकरण प्रयास है।

template< std::size_t I, typename... Ts > 
inline typename std::enable_if< I == sizeof... (Ts), std::tuple<Ts...>& >::type assignadd_impl(std::tuple<Ts...>& lhs, const std::tuple<Ts...>& rhs) 
{ 
    return lhs; 
} 

template< std::size_t I, typename... Ts > 
inline typename std::enable_if< I != sizeof... (Ts), std::tuple<Ts...>& >::type assignadd_impl(std::tuple<Ts...>& lhs, const std::tuple<Ts...>& rhs) 
{ 
    std::get<I>(lhs) += std::get<I>(rhs); 
    return assignadd_impl< I + 1, Ts... >(lhs, rhs); 
} 

template< typename... Ts > 
inline std::tuple<Ts...>& operator +=(std::tuple<Ts...>& lhs, const std::tuple<Ts...>& rhs) 
{ 
    return assignadd_impl< 0, Ts... >(lhs, rhs); 
} 

यह संकलित करता है तथा अपेक्षा के अनुरूप काम करता है। सरलीकृत संस्करण संकलित करने से इंकार क्यों करता है? धन्यवाद।

+0

क्या होगा यदि आप अपने पहले कोड नमूने में 'I' टेम्पलेट पैरामीटर को आगे बढ़ते हैं, जैसे कि यह दूसरे काम में है? क्या यह कुछ बदलता है? –

+0

@ जेरेम्याह विलकॉक - दुर्भाग्य से नहीं। मैंने टेम्पलेट पैरामीटर के क्रम को स्विच करने सहित कई बदलावों की कोशिश की, लेकिन उनमें से सभी एक ही त्रुटि उत्पन्न करते हैं। – pmjobin

उत्तर

4

फ़ंक्शन या क्लास टेम्पलेट के लिए स्पष्ट रूप से निर्दिष्ट टेम्पलेट तर्कों का उपयोग करने के लिए आवश्यक है कि किसी भी टेम्पलेट पैरामीटर पैक समग्र टेम्पलेट पैरामीटर सूची के अंत में दिखाई दें। टेम्पलेट पैरामीटर सूचियों के अंत में Ts... को स्थानांतरित करना और कॉल को उचित रूप से बदलना कोड को काम करता है। the current C++0x draft की धारा 14.8.2.1 बताती है कि पैरामीटर पैक जो टेम्पलेट पैरामीटर सूची के अंत में नहीं हैं, को फ़ंक्शन कॉल से नहीं लिया जा सकता है (जो आपका मूल कोड विफल हो जाता है), लेकिन सभी मामलों में operator+= पर सभी टेम्पलेट तर्कों को स्पष्ट रूप से निर्दिष्ट करना अभी भी एक SFINAE त्रुटि का कारण बनता है। A previous question पर ध्यान देने योग्य सटीक पाठ का एक लिंक है; IBM's documentation कहता है कि यह भी एक त्रुटि है।

+0

यह वास्तव में काम करता है। मुझे नहीं पता कि मेरे मूल परीक्षणों के दौरान क्या गलत हुआ क्योंकि मैंने एक बिंदु पर टेम्पलेट तर्कों को उलटा कर दिया था। लेकिन फिर भी धन्यवाद। :) – pmjobin

संबंधित मुद्दे