2012-06-14 7 views
8

निम्नलिखित कोड में, वैरिएडिक कन्स्ट्रक्टर को दो बार बुलाया जाता है। जब उपयुक्त हो तो वैरिएडिक कन्स्ट्रक्टर के एकल तर्क संस्करण के बजाय मैं कॉपी कन्स्ट्रक्टर को कैसे कॉल कर सकता हूं?मैं एक वैरिएड कन्स्ट्रक्टर पर कॉल कॉपी कन्स्ट्रक्टर कैसे प्राप्त करूं?

#include <iostream> 

struct Foo 
{ 
    Foo(const Foo &) 
    { 
     std::cout << "copy constructor\n"; 
    } 

    template<typename... Args> 
    Foo(Args&&... args) 
    { 
     std::cout << "variadic constructor\n"; 
    } 

    std::string message; 
}; 

int main() 
{ 
    Foo f1; 
    Foo f2(f1); // this calls the variadic constructor, but I want the copy constructor. 
} 

उत्तर

9

इस तथ्य के साथ वास्तव में कुछ भी नहीं है कि निर्माता विविधतापूर्ण है।

struct Foo 
{ 
    Foo() { } 

    Foo(const Foo& x) 
    { 
     std::cout << "copy constructor\n"; 
    } 

    template <typename T> 
    Foo(T&& x) 
    { 
     std::cout << "template constructor\n"; 
    } 

}; 

समस्या यह है कि निर्माता टेम्पलेट एक बेहतर मैच है: एक गैर variadic निर्माता टेम्पलेट के साथ निम्न वर्ग एक ही व्यवहार दिखाता है। कॉपी कन्स्ट्रक्टर को कॉल करने के लिए, गैर-कॉन्स lvalue f1 से const Foo& (कॉन्स्ट योग्यता को जोड़ा जाना चाहिए) को बाध्य करने के लिए योग्यता रूपांतरण की आवश्यकता होती है।

निर्माता टेम्पलेट कॉल करने के लिए कोई भी रूपांतरण की आवश्यकता है: T, Foo& को निष्कर्ष निकाला जा सकता है जो संदर्भ टूट के बाद (Foo& && ->Foo&), पैरामीटर x प्रकार Foo& देता है।

आप एक दूसरी प्रतिलिपि निर्माता प्रदान करके इसके आसपास काम कर सकते हैं जिसमें एक गैर-कॉन्स लैवल्यू संदर्भ पैरामीटर Foo& है।

+1

इसके लिए थोड़ा और अधिक है, अर्थात् संदर्भ ढहना (जिसे कहा जाता था?), यानी 'T &&&' => 'टी &' क्योंकि अन्यथा एक lvalue ('f1')' T && 'से बाध्य नहीं हो सका। –

4

बस एक सटीक मेल खाने वाला अधिभार, अर्थात एक गैर constFoo& के साथ एक पारंपरिक प्रतिलिपि निर्माता के अलावा हैं। फिर आप एक स्पष्ट कलाकार के माध्यम से कॉल का प्रतिनिधि दे सकते हैं:

Foo(Foo& other) : Foo(static_cast<Foo const&>(other)) { }