【发布时间】:2013-07-02 23:24:11
【问题描述】:
假设我正在使用实现函数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;
}
BAM。程序突然中断。这是因为我们实际上想要传入的 sn-p 是一个常量引用,但随着 API 的突然变化,编译器选择了我们不想要的版本,程序意外中断。
我们想要的实际上是这样的:
int main() {
int x = 1;
foo(static_cast<const int &>(x));
std::cout << (1/x) << std::endl;
}
通过此修复程序,程序再次开始工作。但是,我必须说我在代码中没有看到很多这样的转换,因为每个人似乎都只是相信不会发生这种类型的错误。此外,这似乎是不必要的冗长,如果有多个参数并且名称开始变长,函数调用就会变得非常混乱。
这是一个合理的担忧吗?我应该如何解决?
【问题讨论】:
-
这不是
const_cast的用途,它旨在删除一个类型的const限定。static_cast也适用于您的示例。 -
@CaptainObvlious cplusplus.com/doc/tutorial/typecasting 在这里它说“这种类型的转换操纵了对象的常量性,无论是设置还是删除。”这是不正确的吗?
-
@Svalorzen 它可以用于此,但不应该。它不是完成任务的最小工具。该任务的最小工具是
static_cast。 -
如果
foo( int &arg )与foo( const int &arg )具有明显不同的语义,我认为API 设计人员是合适的。我认为,在一个理智的宇宙中,你不应该两者都需要。在你可能需要两者的奇怪情况下(例如,由于函数指针类型限制),似乎非 const 版本应该能够直接转发到 const 版本。 -
所有类型转换都可以添加“常量”到一个类型,但只有
const_cast(以及内部使用const_cast的C风格类型转换)可以删除它。移除 const-qualifier 并不仅仅限制。
标签: c++ function c++11 arguments constants