Disabling pointer output in C++ streams?
如果你把任何指针交给C++流,它的地址将被放入输出。(显然,除非有更具体的输出处理程序。)
1 2 3 4 5 6 7 | void* px = NULL; const char* ps ="Test"; FooType* pf = ...; stringstream s; s << ps <<"" << px <<"" << pf" "; s.str(); // yields, for example:"Test 0 AF120089" |
如果用户错误地试图实际打印footype的值,这可能是一个问题。
在混合宽字符和窄字符时,这也是一个问题,因为您将得到打印的地址而不是编译器错误:
1 2 3 4 | const wchar_t* str = L"Test! (Wide)"; // ... cout << str <<" "; // Ooops! Prints address of str. |
所以我想知道-由于我很少想要输出一个指针值,是否可以禁用指针值的格式设置,以便在流中插入一个指针值会导致编译器错误?(然后,通过使用包装器类型或将指针值强制转换为大小T或其他类似的类型,可以轻松地输出指针值。)
编辑:根据Neil的回答(通过提供自己的void*输出操作符来禁用void*输出),我想补充一点,如果这也适用于boost.format之类的工具,那么隐式使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #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; } |
编辑:此解决方案不能按预期工作,因为模板还捕获字符串文本。你应该更喜欢@neil的解决方案。
如果未注释第二个和/或第三个输出到cout,则在g++中会出现编译错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <iostream> using namespace std; ostream & operator << ( const ostream &, void * ) { } int main() { int n = 0; cout << 0; // cout << &n; // cout << (void *) 0; } |
是的,通过提供自己的ostream运算符<<重载,可以导致编译错误。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #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; } |
保持EDOCX1[1]没有指针提示。
1 2 | template<typename T> std::ostream& operator<<(std::ostream &stream, T* value); |
编辑:或者最好是输入一个无效的类型名来获取编译器错误。