2011-05-23 12 views
8

यदि आप किसी भी पॉइंटर को सी ++ स्ट्रीम में रखते हैं, तो इसका पता आउटपुट में डाल दिया जाएगा। (जाहिर है जब तक कि वहाँ एक अधिक विशिष्ट उत्पादन हैंडलर है।)सी ++ धाराओं में पॉइंटर आउटपुट को अक्षम करना?

void* px = NULL; 
const char* ps = "Test"; 
FooType* pf = ...; 
stringstream s; 
s << ps << " " << px << " " << pf "\n"; 
s.str(); // yields, for example: "Test 0 AF120089" 

यह एक समस्या हो सकती है, यदि उपयोगकर्ता ग़लती से वास्तव में FooType की मूल्य मुद्रित करने के लिए कोशिश कर रहा था।

और यह भी एक समस्या है जब विस्तृत चार और संकीर्ण चार मिश्रण है, क्योंकि एक संकलक त्रुटि के बजाय है, तो आप पता मुद्रित कर देंगे:

const wchar_t* str = L"Test! (Wide)"; 
// ... 
cout << str << "\n"; // Ooops! Prints address of str. 

तो मैं सोच रहा था - के बाद से मैं बहुत मुश्किल से ही चाहते हैं सूचक सूचक को आउटपुट करने के लिए, पॉइंटर मानों के स्वरूपण को अक्षम करना संभव होगा, ताकि स्ट्रीम में पॉइंटर मान डालने से एक कंपाइलर त्रुटि हो सके? (मेरे अपने शून्य प्रदान करके अक्षम करने शून्य * उत्पादनNeil's answer के प्रकाश में *: (सूचक मूल्यों की outputting तो आसानी से एक आवरण प्रकार का उपयोग कर या कास्टिंग सूचक मान size_t या somesuch करने के द्वारा प्राप्त किया जा सकता है।)

संपादित करें आउटपुट ऑपरेटर) मैं यह जोड़ना चाहूंगा कि यह अच्छा होगा अगर यह Boost.Format जैसे टूल के लिए भी काम करता है, जो std नेमस्पेस में परिभाषित आउटपुट ऑपरेटर का अंतर्निहित उपयोग करता है ...

उत्तर

3

यह एक संकलन त्रुटि देता है जी ++ में अगर दूसरा और/या तीसरा आउटपुट कोउट किया गया है तो

#include <iostream> 
using namespace std; 

ostream & operator << (const ostream &, void *) { 
} 


int main() { 
    int n = 0; 
    cout << 0; 
// cout << &n; 
// cout << (void *) 0; 
} 
+0

हमम ... यह ठीक दिखता है। "सामान्य" शून्य * आउटपुट ऑपरेटर नामस्थान std में परिभाषित किया गया है, नहीं? तो अगर कोई कोड है जो std से किसी का उपयोग करता है, तो इससे मदद नहीं मिलेगी ...? –

+0

किंडा काम करता है, लेकिन औपचारिक रूप से आपको कम से कम एक उपयोगकर्ता परिभाषित पैरामीटर प्रकार के बिना ऑपरेटरों को अधिभारित करने की अनुमति नहीं है। –

+1

@ बो और आपको क्या लगता है ओस्ट्रीम है? –

4

operator<< के एक वैश्विक टेम्पलेट संस्करण काम करने के लिए लगता है:

#include <iostream> 
#include <boost/static_assert.hpp> 

template<typename T> 
std::ostream & operator<<(std::ostream & stream, T* value) { 
    BOOST_STATIC_ASSERT(false); 
} 

int main() { 
    int foo = 5; 
    int * bar = &foo; 

    std::cout << bar << std::endl; 
} 

संपादित करें: यह समाधान के रूप में इरादा काम नहीं करता है, के रूप में टेम्पलेट भी स्ट्रिंग शाब्दिक कैप्चर करता है। आपको @ नील के समाधान को प्राथमिकता देना चाहिए।

+0

कूल, ऐसा लगता है कि हम बहुत अधिक जवाब के साथ आए! – xDD

+0

क्या यह वैश्विक नामस्थान में कोड तक ही सीमित नहीं होगा? ऐसा लगता है कि अन्य नेमस्पेस में कोड ':: std :: ऑपरेटर <<' ('std :: cout' पर एडीएल के कारण) मिलेगा लेकिन' :: ऑपरेटर << ' – MSalters

+0

@MSalters नहीं: [ideone यह काम करता है] (http://ideone.com/MaqNp) भले ही कॉल किसी अन्य नामस्थान से आती है। लेकिन सहजता से मैं आपके साथ सहमत होगा। –

1

हां, आप ostream के ऑपरेटर < < का अपना अधिभार प्रदान करके संकलन त्रुटि का कारण बन सकते हैं।

#include <iostream> 

template <typename T> 
std::ostream& operator << (std::ostream& s, T* p) 
{ 
    char ASSERT_FAILED_CANNOT_OUTPUT_POINTER[sizeof(p) - sizeof(p)]; 
} 

int main() 
{ 
    int x; 
    int* p = &x; 
    cout << p; 
} 
+0

जैसा कि मैंने अपने स्वयं के उत्तर के संपादन में उल्लेख किया है, यह इरादे के रूप में काम नहीं करता है, क्योंकि यह आपको प्रिंटिंग स्ट्रिंग अक्षरों से भी रोकता है। –

0

operator << पॉइंटर्स के लिए अनुपूरक रखें।

template<typename T> 
std::ostream& operator<<(std::ostream &stream, T* value); 

संपादित: या बेहतर संकलक त्रुटि प्राप्त करने के लिए गलत typename डाल करने के लिए।

+0

वह एक लिंकर त्रुटि देगा, एक संकलक नहीं, है ना? –

+0

@ नील, सही। मैं इसे अपडेट कर दूंगा। – iammilind

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