2014-05-21 8 views
6

जी ++ 4.9 और बजना 3.4 के साथ परीक्षण, क्यों इस कोड संकलन नहीं करता है:रिकर्सिव noexcept विनिर्देश

namespace { 

template<typename T> 
constexpr auto f(T && t) noexcept { 
    return true; 
} 

template<typename T, typename... Ts> 
constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) { 
    return f(ts...); 
} 

} // namespace 

int main() { 
    f(true, 0, 5u); 
} 

लेकिन इस कोड है:

namespace { 

template<typename T> 
constexpr auto f(T && t) noexcept { 
    return true; 
} 

template<typename T> 
constexpr auto f_helper(T && t) noexcept(noexcept(f(t))) { 
    return f(t); 
} 

template<typename T, typename... Ts> 
constexpr auto f_helper(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) { 
    return f(ts...); 
} 

template<typename T, typename... Ts> 
constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f_helper(ts...))) { 
    return f(ts...); 
} 

} // namespace 

int main() { 
    f(true, 0, 5u); 
} 

f_helper समारोह से परिभाषित करने की जरूरत नहीं है, यह सिर्फ उस मामले में decltype के माध्यम से निर्दिष्ट सही वापसी प्रकार होना चाहिए।

पहला कोड भी 1 या 2 तर्कों के लिए संकलित करता है, लेकिन एक बार जब मैं इसे 3 या उससे अधिक के साथ कॉल करने का प्रयास करता हूं, तो मुझे कॉल करने के लिए कोई मिलान करने वाले फ़ंक्शंस के बारे में त्रुटियां मिलती हैं। पहले कोड के लिए बजना त्रुटि है:

source/main.cpp:9:59: error: call to function 'f' that is neither visible in the template definition nor 
     found by argument-dependent lookup 
     constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) { 
                   ^
source/main.cpp:9:17: note: in instantiation of exception specification for 'f<bool, int, unsigned int>' 
     requested here 
     constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) { 
        ^
source/main.cpp:16:3: note: in instantiation of function template specialization '<anonymous 
     namespace>::f<bool, int, unsigned int>' requested here 
       f(true, 0, 5u); 
       ^
source/main.cpp:9:17: note: 'f' should be declared prior to the call site 
     constexpr auto f(T && t, Ts && ... ts) noexcept(noexcept(f(ts...))) { 
        ^
1 error generated. 
+0

सहायक के साथ संस्करण [संकलित नहीं करता है] (http://coliru.stacked-crooked.com/a/126cee2269269e96) यदि आप f को 4 पैरामीटर पास करते हैं। –

उत्तर

5

3.3.2/1 एक नाम के लिए घोषणा की बात अपनी पूर्ण declarator (क्लॉज 8) के तुरंत बाद है और इसकी प्रारंभकर्ता से पहले (यदि हो तो) ...

अपवाद-विनिर्देश वाक्य रचना declarator का हिस्सा है। इस प्रकार, फ़ंक्शन का नाम अपने अपवाद-विनिर्देश के भीतर दायरे में नहीं है।

+0

हालांकि मैं तकनीकी रूप से वास्तव में इस फ़ंक्शन को बार-बार कॉल नहीं कर रहा हूं, फिर भी मैं एक ही टेम्पलेट से उत्पन्न एक पूरी तरह से अलग फ़ंक्शन को कॉल कर रहा हूं, जो अंततः एकल-तर्क फ़ंक्शन परिभाषा को कॉल करता है। क्या वह मेरी मदद कर सकता है? –

+1

उस फ़ंक्शन टेम्पलेट का नाम उस बिंदु पर नहीं है जहां आप इसका उपयोग करने का प्रयास कर रहे हैं। –

+0

@ डेविडस्टोन मुझे लगता है कि यह एडीएल के माध्यम से पाया जा सकता है? जो चीजों को एक हैक तक खुलता है, जहां आप 'नामस्थान' से एक डमी तर्क के साथ 'टेम्पलेट' फ़ंक्शन कार्यान्वयन बनाते हैं, और कहा गया कार्यान्वयन के मामले में जनता के सामने वाले व्यक्ति को परिभाषित करते हैं। यह काम करता है अगर अनिश्चित है। – Yakk

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