2014-07-07 4 views
20

मैं जबstd :: वेक्टर: करने के लिए बाध्य नहीं कर सकता 'std :: {एसटीडी उर्फ ​​:: basic_ostream <char>} ostream' lvalue 'std :: basic_ostream <char> &&'

के रूप में सरल कुछ करने की कोशिश कर रहा एक भ्रामक त्रुटि संदेश का सामना करना पड़ा
std::cout << std::vector<int>{1,2,3}; 

जो कहते हैं

cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&' 
int main() { std::cout << std::vector<int>{1,2,3}; } 

(-std साथ जीसीसी-4.8.1 का उपयोग कर परीक्षण किया = C++ 11)

अतः जो कुछ के बारे में, Overloading operator<<: cannot bind lvalue to ‘std::basic_ostream<char>&&’ की तरह इसी तरह के सवाल है नेस्टेड कक्षाओं के साथ उपयोगकर्ता परिभाषित वर्ग। उस प्रश्न के स्वीकृत उत्तर के आसपास एक काम भी है।

लेकिन मुझे नहीं पता कि यह std::vector पर लागू होता है या नहीं। क्या कोई यह समझा सकता है कि यह त्रुटि std::vector पर क्यों होती है, और इसकी व्याख्या कैसे करें?

धन्यवाद

उत्तर

20

टेम्पलेट से संबंधित त्रुटि संदेश कई बार भ्रमित हो सकते हैं। समस्या यह है कि std::ostream में मानक लाइब्रेरी (या उस मामले के लिए कोई अन्य कंटेनर) डालने के लिए operator << का अधिभार परिभाषित नहीं करता है। इसलिए संकलक operator << के लिए उपयुक्त अधिभार खोजने में विफल रहता है, और इस विफलता को जितना संभव हो उतना सर्वोत्तम रिपोर्ट करता है (दुर्भाग्यवश दुर्भाग्यवश आपके मामले में बहुत अच्छा/पठनीय नहीं है)।

आप एक पूरे कंटेनर स्ट्रीम करने के लिए चाहते हैं, तो आपको लगता है कि के लिए std::ostream_iterator उपयोग कर सकते हैं:

auto v = std::vector<int>{1, 2, 3}; 
std::copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, " ")); 

आप इसी छुपे त्रुटि क्यों हो रही है का सवाल है, यह पूर्ण त्रुटि संदेश का विश्लेषण करने में मदद करता है :

prog.cpp: In function ‘int main()’: 
prog.cpp:13:37: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’ 
    std::cout << std::vector<int>{1,2,3}; 
            ^
In file included from /usr/include/c++/4.8/iostream:39:0, 
       from prog.cpp:3: 
/usr/include/c++/4.8/ostream:602:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = std::vector<int>]’ 
    operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x) 
    ^

वहाँ जाहिरा तौर पर operator<< की एक टेम्पलेट अधिभार किस प्रकार std::ostream&& के एलएचएस तर्क और एक आरएचएस तर्क ओ लेता है एफ टेम्पलेट प्रकार; यह अस्थायी धाराओं में सम्मिलन की अनुमति देने के लिए मौजूद है। चूंकि यह एक टेम्पलेट है, यह आपके कोड में अभिव्यक्ति के लिए सबसे अच्छा मिलान बन जाता है। हालांकि, std::cout एक लाभा है, इसलिए यह std::ostream&& से बंधे नहीं जा सकता है। इसलिए त्रुटि।

+0

उत्तर के लिए धन्यवाद, जो प्रश्न के पहले भाग को बताता है। मैं मुद्रण वैक्टरों के लिए भी अपना कोड रोल करता हूं। जो मैं समझ नहीं पा रहा हूं (प्रश्न का दूसरा भाग) यह है कि जब हम अधिभार नहीं पा सकते हैं तो हमें इस प्रकार की एल-रेफरी/आर-रेफ त्रुटि मिलती है। – tinlyx

+0

@TingL ने मेरी अनुमान को त्रुटि की प्रकृति के रूप में जोड़ा। – Angew

+0

वह ओवरलोड एक कार्यान्वयन विवरण नहीं है, लेकिन मानक 27.7.1 synopsis द्वारा अस्थायी स्ट्रीम में सम्मिलन की अनुमति देने के लिए आवश्यक है। कुछ ऐसा: 'std :: ofstream (" output.txt ") <<" हाय वहाँ \ n ";' –

-1

कक्षा कक्षा std::vector के लिए operator << परिभाषित नहीं किया गया है।

क्या आप चाहते हैं निम्नलिखित

for (int x : std::vector<int> { 1, 2, 3 }) std::cout << x << ' '; 
std::cout << std::endl; 

हालांकि यह सरल लिखा जा सकता है

for (int x : { 1, 2, 3 }) std::cout << x << ' '; 
std::cout << std::endl; 
8

यह एक ज्ञात जीसीसी के साथ इस मुद्दे, I filed an enhancement request regarding this.

"केवल" समस्या यह है कि है जिस चीज को आप कंसोल पर प्रिंट करने की कोशिश कर रहे हैं, उसके पास operator<< नहीं है। दुर्भाग्यवश, त्रुटि संदेश बहुत उपयोगी नहीं है। :(

वैसे, प्रश्न vector या एल-वैल्यू और आर-वैल्यू संदर्भों से कोई लेना देना नहीं है।एक न्यूनतम उदाहरण:

#include <iostream> 

struct A { }; 

int main() { 
    A a; 
    std::cout << a; 
} 

गोर विवरण के लिए वृद्धि अनुरोध पर चर्चा देखें। संक्षेप में, जीसीसी डेवलपर्स ने पहले से ही त्रुटि संदेश में सुधार करने की कोशिश की थी लेकिन यह कुख्यात रूप से मुश्किल साबित हुआ।

क्या इसके लायक है के लिए, clang's error message libC++ के साथ मेरी राय में स्पष्ट है:

clang++ -std=c++11 -stdlib=libc++ -lc++abi main.cpp && ./a.out 
main.cpp:7:15: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'A') 
    std::cout << a; 
    ~~~~~~~~~^~ 

इधर, पहली पंक्ति स्पष्ट रूप से कहते हैं कि समस्या क्या है।

+0

जबकि कंपाइलर का आउटपुट बेहतर हो सकता है, रिपोर्ट की गई त्रुटि मानक के संदर्भ में सभी समझ में आता है। यह संकलन करने में विफल रहता है और तर्क के अंतराल को छोड़कर * लगभग * मैचों में एक ओवरलोड होता है ... मैं देखता हूं कि * बग * वास्तविक बग की तुलना में एक वृद्धि अनुरोध की तरह है। –

+1

@ डेविडरोड्रिगुएज़-ड्राईबीस मैंने अपना जवाब संशोधित किया और "बग रिपोर्ट" को "एन्हांसमेंट अनुरोध" में बदल दिया। वह "बग" कहने वाला एकमात्र स्थान था। समस्या को जल्दी से पहचानना मेरे लिए बहुत महत्वपूर्ण है। जब मैं पहली बार इस समस्या में भाग गया, तो मुझे कुछ समय लगता है कि क्या हो रहा है; त्रुटि संदेश ने मुझे गलत ट्रैक पर रखा। जैसा कि यह सवाल दिखाता है, मैं अकेला नहीं हूं जिसने उस त्रुटि संदेश को समझने में कठिनाइयों का सामना किया था। खैर, इस मुद्दे को एक वृद्धि अनुरोध या जो भी आप चाहते हैं, यहां तक ​​कि जीसीसी डेवलपर्स यह भी मानते हैं कि यह एक मुद्दा है और इसे सुधारने की कोशिश की गई है। तो यह * एक मुद्दा है। – Ali

+0

@ डेविडरोद्रिगुएज़-ड्राईबीस ठीक है, मैंने कई जगहों पर शब्द को संशोधित किया है, शायद यह बहुत मजबूत था। मुझे आशा है कि अब आप इसे ठीक कर पाएंगे, इस पर मेरा ध्यान आकर्षित करने के लिए धन्यवाद। – Ali

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