2012-03-10 8 views
11

एंड्री अलेक्जेंड्रेस्कू ने एक उत्कृष्ट वार्ता दी: Variadic Templates are Funadicवैराडिक टेम्पलेट्स - विस्तार के विभिन्न प्रकार

template <class... Ts> void fun(Ts... vs) { 
    gun(A<Ts...>::hun(vs)...); 
    gun(A<Ts...>::hun(vs...)); 
    gun(A<Ts>::hun(vs)...); 
} 

वे बताते हैं:

कॉल 1: class A की instatiation के लिए सभी Ts का विस्तार, फिर hun(vs) तब फैलता कॉल

वह निम्नलिखित 3 विस्तार जो subltey अलग हैं प्रस्तुत करता है gun

में उन्हें पास करते समय सभी पैरामीटर दोबारा

कॉल 2: का विस्तार सभी Ts और सभी vs अलग

कॉल 3: ताला कदम है, यानी में Expnads: Ts का तर्क 1 और vs का तर्क 1 विस्तृत Ts का तर्क 2 का विस्तार करें और vs का तर्क 2 Ts का तर्क n और vs

अन्य चर्चा का तर्क n variadic templ पर विस्तार एट्स केवल साधारण वैरैडिक क्लास टेम्पलेट्स और वेरिएफ फ़ंक्शन जैसे विविधता कार्यों को कवर करने लगते हैं। मुझे इस बात के बारे में अनिश्चितता है कि इन विभिन्न प्रकार के विस्तार कोड को कैसे प्रभावित करते हैं और जहां प्रत्येक प्रकार उपयोगी होगा।

क्या किसी के पास कुछ उदाहरण हैं जो प्रत्येक प्रकार के विस्तार के आवेदन को प्रदर्शित करते हैं?

+0

[वैराडिक टेम्पलेट्स पैक विस्तार] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/9182251/variadic-templates-pack-expansions) – kennytm

+0

@ केनीटीएम जो डुप्लिकेट नहीं है। यह लड़का प्रत्येक प्रकार के विस्तार के उदाहरण चाहता है (जरूरी नहीं कि केवल उन तीनों जिन्हें एलेक्सेंड्रेसु दिखाया गया हो, और जो उन्होंने दिखाया वह केवल दो प्रकार का विस्तार है (एक टेम्पलेट तर्कसूची में से एक है, और एक फ़ंक्शन तर्क सूची में))। –

+1

... लेकिन जैसा कि उन्होंने एक जवाब स्वीकार किया जो केवल उन दो प्रकार के विस्तार को दिखाता है, मुझे लगता है कि या तो सवाल कमजोर था या मुझे प्रश्नों की समझ में कमी थी या दोनों ... –

उत्तर

15
#include <iostream> 
#include <memory> 
#include <typeinfo> 
#include <cstdlib> 
#include <cxxabi.h> 

template <typename T> 
std::unique_ptr<char, void(*)(void*)> 
type_name() 
{ 
    return std::unique_ptr<char, void(*)(void*)> 
      (
       __cxxabiv1::__cxa_demangle(typeid(T).name(), nullptr, 
              nullptr, nullptr), 
       std::free 
      ); 
} 

void display() {} 

template <class T> 
void 
display() 
{ 
    std::cout << type_name<T>().get() << ' '; 
} 

template <class T, class T2, class ...Tail> 
void 
display() 
{ 
    std::cout << type_name<T>().get() << ' '; 
    display<T2, Tail...>(); 
} 

template <class... Ts> 
struct A 
{ 
    template <class... Us> 
     static 
     int 
     hun(Us... us) 
     { 
      std::cout << "A<"; 
      display<Ts...>(); 
      std::cout << ">::hun("; 
      display<Us...>(); 
      std::cout << ")\n"; 
      return 0; 
     } 
}; 

template <class ...T> 
void gun(T...) {} 

template <class... Ts> void fun(Ts... vs) 
{ 
    std::cout << "gun(A<Ts...>::hun(vs)...);\n"; 
    gun(A<Ts...>::hun(vs)...); 
    std::cout << "\ngun(A<Ts...>::hun(vs...));\n"; 
    gun(A<Ts...>::hun(vs...)); 
    std::cout << "\ngun(A<Ts>::hun(vs)...);\n"; 
    gun(A<Ts>::hun(vs)...); 
} 

int main() 
{ 
    fun(1, 'a', 2.3); 
} 

आउटपुट:

gun(A<Ts...>::hun(vs)...); 
A<int char double >::hun(int) 
A<int char double >::hun(char) 
A<int char double >::hun(double) 

gun(A<Ts...>::hun(vs...)); 
A<int char double >::hun(int char double) 

gun(A<Ts>::hun(vs)...); 
A<int >::hun(int) 
A<char >::hun(char) 
A<double >::hun(double) 
+0

दूसरा विस्तार सीधे आगे लगता है। अन्य 2 दिलचस्प हैं लेकिन उत्पादन कोड में उपयोग किए जाने पर शायद भ्रम पैदा हो जाएंगे। क्या आप इसे वास्तविक दुनिया परिदृश्य में देखने की उम्मीद करेंगे? – mark

+4

मेरे लिए यह कहना मुश्किल है। मैं अनुमान लगा रहा हूं कि हम एक उद्योग के रूप में शायद अभी भी सीख रहे हैं कि वेरिएडिक टेम्पलेट्स का उपयोग कैसे करें। अब से कुछ वर्षों में कोई अन्य दो रूपों का उपयोग करने के लिए वास्तव में निफ्टी रास्ता खोज सकता है और यह एक पैटर्न बन सकता है।'9 8 में मैंने कभी अनुमान लगाया नहीं होगा कि मैं 'enable_if' जैसी चीजों का उपयोग कर रहा हूं और फिर भी मैं अब हर समय करता हूं। सी ++ एक जीवित, बढ़ती भाषा है! :-) –

7

मामले में 2 और 3 वास्तव में variadic पैक शामिल कोड के किसी भी प्रकार में बहुत आम हैं।

template<typename... T> 
void f(T&&... t) 
{ 
    // Case 2: 
    auto t2 = std::tuple<T...>(t...); 

    // Case 3: 
    auto t3 = std::make_tuple(std::forward<T>(t)...); 
} 

मेरे अपने कोड को देखते हुए, मैं मामले 1. मैं एक सहायक tempate के लिए कुछ detail नाम स्थान में अतीत में यह प्रयोग किया जाता है हो सकता है की किसी भी जीवित उदाहरण नहीं मिल सकता है, लेकिन मुझे यकीन है कि नहीं हूँ। मुझे नहीं लगता कि यह ज्यादातर समय या सामान्य रूप से आवश्यक होगा।

+0

उदाहरणों के लिए धन्यवाद – mark