2015-05-12 8 views
8
#include <string> 
#include <iostream> 
#include <tuple> 
#include <utility> 


template<typename... T> struct test { 

    using args_type = std::tuple<T...>; 

    args_type x; 

    template<std::size_t... I> 
    void callme(std::index_sequence<I...>) { 
     int _[] = {(std::get<I>(x).std::tuple_element<I, args_type>::type::~type(), true)...}; 
    } 
}; 

int main() { 
} 

त्रुटि संदेशक्लैंग ++ कंपाइलर निम्न वैरिएड टेम्पलेट कोड को संकलित करने में विफल क्यों होता है?

clang-3.7 -std=gnu++1y -Wc++14-extensions test.cpp 
test.cpp:15:56: error: expected ')' 
     int _[] = {(std::get<I>(x).std::tuple_element<I, args_type>::type::~type(), true)...}; 
                ^
test.cpp:15:20: note: to match this '(' 
     int _[] = {(std::get<I>(x).std::tuple_element<I, args_type>::type::~type(), true)...}; 
       ^
1 error generated. 

एक ही कोड जी के साथ ++ 4.9.2 ठीक संकलित करने के लिए लगता है। मुझे अभी तक क्लैंग पर कोई प्रासंगिक बग रिपोर्ट नहीं मिली।

+1

कहाँ बजना 3.7 की इस प्रति से आया? एलएलवीएम की सबसे हालिया रिलीज केवल 3.6 है। –

+1

@BillLynch svn। – Columbo

+1

क्या यह 3.6 के साथ संकलित करता है? – Qix

उत्तर

10

हालांकि इस तरह के छद्म नाशक-नामों में से देखने शायद देशद्रोही है और खुले राष्ट्रमंडल खेलों के मुद्दों का विषय है, विशेष रूप से 555 और 399.

विस्तार पैटर्न के महत्वपूर्ण बिट

है, एक बजना बग प्रतीत होता है
std::get<I>(x).std::tuple_element<I, args_type>::type::~type() 

यहाँ, . और () के बीच बिट एक छद्म नाशक नाम है; योग्य नाम लुकअप तो जनादेश कि

एक छद्म नाशक नाम (5.2.4) एक नेस्टेड-नाम-विनिर्देशक, हैं, तो प्रकार- नाम रों में प्रकार के रूप में देखा जाता है नेस्टेड-नाम-विनिर्देश द्वारा निर्दिष्ट दायरा। इसी तरह, एक योग्य-आईडी फार्म के में:

                नेस्टेड-नाम-विनिर्देशक ऑप्ट   वर्ग नाम:: ~वर्ग नाम

दूसरा वर्ग-नाम पहले के समान दायरे में देखा जाता है।

आईई। typestd::tuple_element<I, args_type> में देखा गया है, जहां यह किसी प्रकार के संदर्भ में मिलता है। ध्यान दें कि वर्ग-नाम पहचानकर्ताओं (और सरल-टेम्पलेट-आईडी एस) के लिए एक व्याकरणिक नाम है, और वास्तविक वर्ग को संदर्भित करने की आवश्यकता नहीं है। std::get<I>(x).std::tuple_element<I, args_type>::type::~type तब type के विनाशक को संदर्भित करता है। एक सहायक समारोह के साथ

वर्कअराउंड:

template <typename T> 
void destroy(T& p) {p.~T();} 

template<typename... T> struct test { 
    using args_type = std::tuple<T...>; 

    args_type x; 

    template<std::size_t... I> 
    void callme(std::index_sequence<I...>) { 
     int _[] = {(destroy(std::get<I>(x)), 0)...}; 
    } 
}; 
+0

मैं एक रिपोर्ट दर्ज करूंगा। अजीब है कि। – Qix

+1

विनाशक नाम लुकअप के लिए विनिर्देश गड़बड़ी के सभी प्रकार है। इसके बारे में कम से कम एक लंबे समय तक कोर मुद्दा है। –

+0

@ टी.सी. मुझे अभी एहसास हुआ कि यह वास्तव में कितना अजीब है। – Columbo

0

दिलचस्प है, आईबीएम mentioned से एक coupleworkarounds कि बेहतर काम hstong।

int _[] = {(std::get<I>(x).::std::tuple_element<I, args_type>::type::~type(), true)...}; 

या

int _[] = {(std::get<I>(x).std::template tuple_element<I, args_type>::type::~type(), true)...}; 
संबंधित मुद्दे