c++ - 将 nullptr 传递给我的重载函数会导致运行时错误
问题描述
为了了解更多使用指令和函数重载,我尝试了这个程序:
namespace ns{
void f(int){cout << "int\n";}
void f(double){cout << "double\n";}
void f(std::string){cout << "string\n";}
struct Foo{};
}
void f(ns::Foo const&){
cout << "ns::Foo\n";
}
namespace bin{
void f(int*){
std::cout << "bin::f(int*)\n";
}
}
int main(){
using namespace ns;
//using namespace bin;
f(7); // int
f(7.5); // double
f(ns::Foo{}); // ns::Foo
try{
f(nullptr);
}
catch(std::exception const& e){
std::cout << e.what() << std::endl;
}
}
当我运行程序时,它工作正常,除了最后一次调用f(nullptr)
导致运行时错误:
int
double
ns::Foo
basic_string::_M_construct null not valid
如果我取消注释using
namespace 的指令bin
,则代码可以正常工作。
using namespace bin;
输出:
int
double
ns::Foo
bin::f(int*)
解决方案
当using namespace bin;
被注释掉时,只有 1 个f()
可用版本可以将 anullptr
作为输入。nullptr
不能隐式转换为int
or double
,因此ns::f(int)
和ns::f(double)
被排除。但是std::string
可以从 a 构造const char*
,并且nullptr
可以隐式转换为const char*
,因此编译器可以构造一个临时std::string
对象来传递给ns::f(std::string)
。但是,从 null构造 a是未定义的行为,因此会出现运行时错误(顺便说一句,这是不能保证的,因为行为是未定义的,所以任何事情都可能发生)。std::string
const char*
如果using namespace bin;
未注释掉,则有 2 个f()
可用版本可以将 anullptr
作为输入。 bin::f(int*)
是比 更好的匹配ns::f(std::string)
,因为nullptr
它可以隐式转换为int*
,因此无需构造临时对象,因此编译器选择调用bin::f(int*)
而不是ns::f(std::string)
.
推荐阅读
- azure - 如何在 Azure DevOps 中发出非阻塞拉取请求?拉取请求完成后如何批准?
- java - 视频未使用 VideoView 中的链接播放
- javascript - 即使在javascript中的页面刷新时如何保留范围滑块的最后拖动位置
- java - 如何获取所有后台运行进程列表?
- html - 我有一个轮播在桌面上一次显示 4 张图像。我希望在移动视图中一次只显示一张图像
- java - JFrame Keylistener 正在接受用户的输入
- sql - JOIN 中的复杂 SQL 查询
- javafx - 在 JavaFX 中同步倒数计时器的最佳方法
- c++ - 将字符串转换为无符号字符数组/字节数组
- javascript - 鼠标悬停时不调用和更改背景颜色的函数