开发者

Disabling pointer output in C++ streams?

If you hand any pointer to a C++ stream, it's address will be put into the output. (Obviously unless there's a more specific output handler.)

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

This can be a problem, if the user erroneously was trying to actually print the value of FooType.

And it is also a problem when mixing wide char and narrow char, because instead of a compiler error, you'll get the address printed:

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

So I was wondering - since I very rarely want to output a pointer value, would it be possible to disable formatting of pointer values, so that inserting a pointer value into a stream would result in a compiler error? (Outputting of pointer values could then be easily achieved by using a wrapper type or casting the pointer values to size_t or somesuch.)

Edit: In light of Neil's answer (disabling void* output by providing my own void* output operator) I would like to add that it would be nice if this also worked for tools such as Boost.Format, that make implicit use of the output operator def开发者_如何学编程ined in the std namespace ...


This gives a compilation error in g++ if the second and/or third output to cout is uncommented:

#include <iostream>
using namespace std;

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


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


A global template version of operator<< seems to work:

#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;
}

Edit: This solution does not work as intended, as the template also captures string literals. You should prefer @Neil's solution.


Yes, you can cause a compilation error by providing your own overload of ostream's operator <<.

#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;
}


Keep the operator << unimplemented for pointers.

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

Edit: Or better to put an invalid typename to get compiler error.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜