c++ - 防止采用 const std::string& 的函数接受 0
问题描述
值得一千字:
#include<string>
#include<iostream>
class SayWhat {
public:
SayWhat& operator[](const std::string& s) {
std::cout << s << "\n";
return *this;
}
};
int main() {
SayWhat ohNo;
// ohNo[1]; // Does not compile. Logic prevails.
ohNo[0]; // you didn't! this compiles.
return 0;
}
将数字 0 传递给接受字符串的括号运算符时,编译器不会抱怨。相反,这会在进入方法之前编译并失败:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
以供参考:
> g++ -std=c++17 -O3 -Wall -Werror -pedantic test.cpp -o test && ./test
> g++ --version
gcc version 7.3.1 20180303 (Red Hat 7.3.1-5) (GCC)
我猜
编译器隐式使用std::string(0)
构造函数进入方法,这会产生同样的问题(谷歌上面的错误),没有充分的理由。
问题
无论如何要在类方面解决这个问题,所以 API 用户不会感觉到这一点,并且在编译时检测到错误?
也就是说,添加一个重载
void operator[](size_t t) {
throw std::runtime_error("don't");
}
不是一个好的解决方案。
解决方案
原因std::string(0)
是有效的,是由于0
是一个空指针常量。所以 0 匹配带有指针的字符串构造函数。然后代码与不能将空指针传递给std::string
.
只有文字0
会被解释为空指针常量,如果它是运行时值,则不会出现此问题(因为重载解决方案将改为int
寻找转换)。int
字面量也不是1
问题,因为1
它不是空指针常量。
由于这是一个编译时问题(文字无效值),您可以在编译时捕获它。添加此表单的重载:
void operator[](std::nullptr_t) = delete;
std::nullptr_t
是 的类型nullptr
。它将匹配任何空指针常量,无论是0
、0ULL
还是nullptr
. 并且由于该函数被删除,在重载解析期间会导致编译时错误。
推荐阅读
- javascript - 想要重定向回 index.php
- c# - 如何找到 NotSupportedException 的根本原因?
- sql-server - 在阶段设置主键
- jquery - 为处理 CORS 问题而构建的代理问题
- android - 将数据发送到下一页时出现问题
- c - '\n' 在 memset (C) 之后保存在数组中
- java - Spring Autowired 实例在每个请求上总是相同的
- java - 如何远程读取android应用程序的java堆?
- amazon-web-services - Kubernetes - 没有选择器的服务
- flutter - 如何使用“webview_flutter”获得偏移量?