API上函数参数的一致性更改
Const-correctness of function parameters on API changes
假设我使用的是一个实现函数foo
的库,我的代码可能如下所示:
void foo(const int &) { }
int main() {
int x = 1;
foo(x);
std::cout << (1/x) << std::endl;
}
一切都很好。但现在假设foo
由于某种原因被修改或过载。现在我们得到的可能是这样的东西:
void foo(int & x) {
x--;
}
void foo(const int &) {}
int main() {
int x = 1;
foo(x);
std::cout << (1/x) << std::endl;
}
砰。程序突然中断。这是因为我们实际上想要传递的代码片段是一个常量引用,但随着API的突然变化,编译器选择了我们不想要的版本,程序意外中断。
实际上我们想要的是:
int main() {
int x = 1;
foo(static_cast<const int &>(x));
std::cout << (1/x) << std::endl;
}
通过此修复,程序将重新开始工作。然而,我必须说,我在代码中没有看到过很多这样的强制转换,因为每个人似乎都相信这种类型的错误不会发生。此外,这似乎是不必要的冗长,如果有多个参数并且名称开始变长,函数调用就会变得非常混乱。
这是合理的担忧吗?我应该如何处理?
如果您更改一个接受常量引用的函数,使其不再是常量,那么您可能会破坏它。这意味着您必须检查调用该函数的每个地方,并确保它是安全的。在这种情况下,进一步使用两个同名函数,一个带const,另一个不带const肯定是一个糟糕的计划。
正确的做法是创建一个新函数,该函数使用与现有函数不同的名称来执行x--
变体。
任何API供应商如果做了这样的事情,都应该受到严厉的惩罚,如果文档中有一个BIG通知,说"我们已经更改了函数foo
,现在它会递减x
,除非参数被强制为const",则可能会少一些暴力行为。这是人们能想象到的最糟糕的二进制中断之一(就"很难找出问题所在"而言)。
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 视图中的参数推导失败:take_while
- 与具有字符串输出参数的 WinAPI 函数的一致性是多少
- API上函数参数的一致性更改
- 捕获函数参数中的一致性
- 是否可以参数化模板化成员函数的一致性