2013-05-05 4 views
7

के वेक्टर वाले ऑब्जेक्ट्स की एक सूची को सॉर्ट करना निम्नलिखित कोड को C++ 11 (यदि ऐसा है?) के अनुसार संकलन त्रुटि उत्पन्न करना है या यह VC11 के साथ कोई समस्या है?अद्वितीय_ptr

#include <vector> 
#include <list> 
#include <memory> 
struct A 
{ 
    std::vector<std::unique_ptr<int>> v; 
}; 
int main() 
{ 
    std::list<A> l; 
    l.sort([](const A& a1, const A& a2){ return true; }); 
} 

विजुअल C++ 2012 निम्नलिखित संकलन त्रुटि पैदा करता है:

1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(606): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>' 
1>   with 
1>   [ 
1>    _Ty=int 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1447) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr' 
1>   with 
1>   [ 
1>    _Ty=int 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(605) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)' 
1>   with 
1>   [ 
1>    _Ty=std::unique_ptr<int> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(751) : see reference to function template instantiation 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)' being compiled 
1>   with 
1>   [ 
1>    _Ty=std::unique_ptr<int> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 11.0\vc\include\type_traits(743) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled 
1>   with 
1>   [ 
1>    _Ty=std::unique_ptr<int> 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 11.0\vc\include\vector(655) : see reference to class template instantiation 'std::is_empty<_Ty>' being compiled 
1>   with 
1>   [ 
1>    _Ty=std::allocator<std::unique_ptr<int>> 
1>   ] 
1>   d:\test2\test2.cpp(213) : see reference to class template instantiation 'std::vector<_Ty>' being compiled 
1>   with 
1>   [ 
1>    _Ty=std::unique_ptr<int> 
1>   ] 
+0

संदर्भ के लिए, मैं क्लैंग और जीसीसी में इसे ठीक से संकलित कर सकता हूं। तो यह या तो आपका कंपाइलर या आपकी सेटिंग्स है। – chrisaycock

+0

@chrisaycock ओह ठीक है, माइक्रोसॉफ्ट कनेक्ट पर एक और वीसी 11 बग रिपोर्ट बनाने जा रहा है ... – PowerGamer

+3

मैं इसे पूरी तरह से छोड़ दूंगा। –

उत्तर

0

यह दृश्य सी के साथ एक मुद्दा था ++ 2012 (कनेक्ट पर Microsoft द्वारा स्वीकार किया: Compile error in C++ code sorting a list of objects holding a vector of unique_ptr) और यह पहले से ही विज़ुअल सी में तय किया गया था ++ 2013

इसके अलावा, मैं एक मुद्दा है कि बाहर बिंदु करना चाहते हैं इस तथ्य से कोई लेना-देना नहीं था, कि दृश्य सी ++ स्पष्ट रूप से चालक रचनाकार उत्पन्न नहीं करता है। यदि आप स्पष्ट रूप से सभी प्रतिलिपि हटाते हैं और संरचना ए में रचनाकारों को स्थानांतरित करते हैं (हां, यह सूची में टाइप ए की असंभव डालने वाली वस्तुएं बना देगा, लेकिन यह बिंदु के बगल में है) मेरे मूल उदाहरण में कोड को अभी भी प्रतिलिपि बनाना या स्थानांतरित करना नहीं है ऑब्जेक्ट्स और इस तरह के उपज संकलन त्रुटियों के रूप में:

#include <vector> 
#include <list> 
#include <memory> 
struct A 
{ 
    std::vector<std::unique_ptr<int>> v; 
    A(A&&) = delete; 
    A(const A&) = delete; 
}; 
int main() 
{ 
    std::list<A> l; 
    l.sort([](const A& a1, const A& a2){ return true; }); 
} 
4

यह "कुलपति के साथ एक समस्या" है, लेकिन सिर्फ इसलिए कि आप दृश्य स्टूडियो का दुरुपयोग कर रहे हैं।

वीसी ++ आर-वैल्यू संदर्भ लागू करता है, लेकिन यह संकलक-जनरेटेड चाल कन्स्ट्रक्टर/असाइनमेंट ऑपरेटर लागू करता है। जिसका अर्थ यह है कि, यदि आप एक प्रकार को स्थानांतरित करने के लिए चाहते हैं, तो आपको खुद को लिखना होगा।

A एक चलने योग्य प्रकार नहीं है, इसलिए विभिन्न std::list फ़ंक्शन उन्हें कॉपी करने का प्रयास करेंगे। और वे unique_ptr के vector की प्रतिलिपि बनाने का प्रयास करते समय विफल हो जाएंगे। इसलिए संकलक त्रुटि।

यदि आप वीसी ++ में स्थानांतरित जागरूकता चाहते हैं, तो आपको स्वयं के लिए चाल रचनाकार/असाइनमेंट लिखना होगा।

+2

क्यों एक सूची सॉर्ट करना (एक वेक्टर नहीं) किसी चीज की प्रतिलिपि बनाने की आवश्यकता है? सॉर्टिंग को डबल-लिंक्ड सूची नोड्स के "पिछले" और "अगले" पॉइंटर्स को बदलकर कार्यान्वित नहीं किया जाना चाहिए? – PowerGamer

3

समस्या वास्तव में वीसी 11 में है, it doesn't implement C++11 feature of automatically generating move operations (जैसा कि पहले से ही निकोल बोलास द्वारा खींचा गया है)।

निम्नलिखित कोड वीसी 10 एसपी 1 के साथ संकलित करता है; इस कोड नमूने में, कन्स्ट्रक्टर को स्पष्ट रूप से लिखा गया है (इसके बजाय operator= स्थानांतरित करने के लिए, copy-and-swap idiom का उपयोग किया जाता है)।

#include <algorithm> // for std::swap (for copy-and-swap idiom) 
#include <list> 
#include <memory> 
#include <vector> 

struct A 
{ 
    std::vector<std::unique_ptr<int>> v; 

    A(A&& other) 
     : v(std::move(other.v)) 
    { 
    } 

    A& operator=(A other) 
    { 
     swap(*this, other); 
     return *this; 
    } 

    friend void swap(A& lhs, A& rhs) 
    { 
     using std::swap; 
     swap(lhs.v, rhs.v); 
    } 
}; 

int main() 
{ 
    std::list<A> l; 
    l.sort([](const A& , const A&){ return true; }); 
} 
+1

मुझे पता है कि किस चालक कन्स्ट्रक्टर है और तथ्य यह है कि वीसी 11 उन्हें स्पष्ट रूप से उत्पन्न नहीं करता है। यह थोड़ी सी में व्याख्या नहीं करता है क्यों वीसी 11 एक * सूची * के क्रमबद्ध प्रदर्शन करते समय टाइप ए की ऑब्जेक्ट कॉपी या स्थानांतरित करना चाहता है। – PowerGamer

+0

ठीक है, तो आपको एसटीएल स्रोत कोड में जवाब मिल सकता है। मैं तुम्हारा मुद्दा समझता हूँ। –

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