2016-06-19 18 views
6

नीचे कोड पर विचार करें एक बजना के बग है:इसकी एक और विशेषज्ञता से विरासत टेम्पलेट कर सकते हैं एक सर्कुलर निर्भरता है या यह

#include <iostream> 
#include <utility> 
#include <tuple> 

template <class TargetIndices, class SourceIndices> 
struct assign; 

template <size_t... TargetIs, size_t... SourceIs> 
struct assign<std::index_sequence<TargetIs...>, std::index_sequence<SourceIs...>>: assign<std::index_sequence<TargetIs>, std::index_sequence<SourceIs>>... { 
    template <class TargetTuple, class SourceTuple> 
    assign(TargetTuple &target, const SourceTuple &source): assign<std::index_sequence<TargetIs>, std::index_sequence<SourceIs>>(target, source)... { } 
}; 

template <size_t FirstTI, size_t FirstSI> 
struct assign<std::index_sequence<FirstTI>, std::index_sequence<FirstSI>> { 
    template <class TargetTuple, class SourceTuple> 
    assign(TargetTuple &target, const SourceTuple &source) { 
     std::get<FirstTI>(target) = std::get<FirstSI>(source); 
    } 
}; 


int main() { 
    std::tuple<int, int, int> t1 = std::make_tuple(0,0,0), t2 = std::make_tuple(1,2,3); 
    assign<std::index_sequence<0,2>, std::index_sequence<2,0>>(t1, t2); 
    std::cout << std::get<0>(t1) << " " << std::get<1>(t1) << " " << std::get<2>(t1) << std::endl; 
} 

बजना ++ में कहा गया है विरासत में एक सर्कुलर निर्भरता नहीं है। g ++ किसी भी समस्या के बिना इसे संकलित करता है। कौन सा कंपाइलर सही है?

उत्तर

6

यह एक क्लैंग बग की तरह दिखता है।

एक न्यूनतम प्रजनन इस तरह दिखता है:

template <int...> struct q {}; 

template <int... Is> using w = q<Is...>; 

template <class T> 
struct a; 

template <int F> 
struct a<w<F>> {}; 

template <int... T> 
struct a<w<T...>>: a<w<T>>... {}; // g++ OK, clang++ breaks 

टेम्पलेट उर्फ ​​यहाँ आवश्यक है। जब मूल टेम्पलेट का उपयोग टेम्पलेट उपनाम के बजाय अंतिम पंक्ति में किया जाता है, तो यह संकलित करता है:

struct a<q<T...>>: a<q<T>>... {}; // g++, clang++ OK 
संबंधित मुद्दे