空 PTR 的运算符<<(流输出)
operator << (stream output) for nullptr
考虑一段通用C++代码,它向流输出其参数的值,以防它们不相等:
#define LOG_IF_NE(a, b) if(a != b) {
std::cerr << "Failed because (" << ##a << "=" << (a) <<
") != (" << ##b << "=" << (b) << ")";
}
这只是一个例子,实际代码在将消息写入字符串流后抛出异常。这对于定义了流operator <<
的2个整数、2个指针等都很好。
int g_b;
int f(int a)
{
LOG_IF_NE(a, g_b);
// implementation follows
}
当LOG_IF_NE
的参数之一是nullptr
时会出现问题:MSVC++2013编译器给出error C2593: 'operator <<' is ambiguous
。
int *pA;
int g()
{
LOG_IF_NE(pA, nullptr);
}
出现此问题的原因是nullptr
具有特殊类型,而STL中没有为该类型定义operator <<
。答案在https://stackoverflow.com/a/21772973/1915854建议为std::nullptr_t
定义operator <<
//cerr is of type std::ostream, and nullptr is of type std::nullptr_t
std::ostream& operator << (std::ostream& os, std::nullptr_t)
{
return os << "nullptr"; //whatever you want nullptr to show up as in the console
}
这是解决问题的正确方法吗?没有为nullptr_t
定义operator<<
,这不是C++11/STL中的一个错误吗?C++14/17中是否需要修复?或者这是故意的(因此,一个人对operator<<
的私人定义可能会有缺陷)?
这是LWG#2221,它提出:
显而易见的库解决方案是添加一个
nullptr_t
过载,该过载将被定义为类似的东西template<class C, class T> basic_ostream<C, T>& operator<<(basic_ostream<C, T>& os, nullptr_t) { return os << (void*) nullptr; }
我们还可以考虑在核心级别上解决这个问题:添加一个特殊情况的语言规则,该规则可以解决所有编写
f(nullptr)
和f
在多个指针类型上重载的情况。(也许是决胜局说void*
在这种情况下更可取。)
它不在C++14中,我不知道它是否会进入C++17。这是一个很容易自己解决的问题,所以就标准更改而言,这并不是特别重要的问题。正如你在问题中所说的,这只是一个3行函数。
我认为这可能是故意的,原因与nullptr
本身的价值相同。在这种情况下默默地接受它可能被视为潜在的违反先决条件和不变量的行为。
nullptr
是一个值,用于初始化指向的指针,以检测其是否尚未初始化。因此,按照这种逻辑,无论如何实际使用它都应该是明确的,并记录在案,以防止滥用和潜在的安全漏洞。简单地重载操作员打印出来无论如何都不会提供这种功能。
在调试环境中(宏将调用home),如果您要检查不变量和具有良好定义的输出的程序逻辑,则在条件编译中使用断言更有意义。
这基本上可以归结为一个设计点:在可以从中最好地恢复错误的地方处理错误。您的宏测试不等式,但如果它发现nullptr
,则该宏处理该错误是没有意义的,因此重新进行异常处理更有意义,这样问题就可以被抛出到可以处理nullptr
并从中恢复的地方。否则,您将允许程序处于不一致或不安全的状态。
编辑:刚刚看到您实际上在使用异常处理。嵌套的try/catch可能是最佳的,因为您可以在可以处理这两个错误的地方捕获它们。
- 递归函数计算序列中的平方和(并输出过程)
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 请解释"函数1(p1,p2,p3);"的输出
- C++:将控制台输出存储在宏中更好吗
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 为什么我的代码在输出中增加了93天
- 如何从void函数输出字符串
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- 呼叫运营商<<临时
- AES加密到解密未正确输出
- 如何将c++程序的一些输出传递给shell,以便在shell中使用
- 使用C++程序合并排序没有得到正确的输出
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- C++格式化输出问题
- 过载输出<<用于类的运算符,以打印其中的元组
- 重载运算符<<输出地址而不是数据成员
- 什么会导致死亡<<变量& lt; & lt;“ t";当输出超过终端宽度时,打印空白而不是值
- Can运算符<<用于设计我们自己的输出显示方式