是否有可能使const&
真正不可变?
int* side_effect;
void function(int const& i){
*side_effect = 123;
}
int main(){
int i = 0;
side_effect = &i;
//based on the function signature, i is suspected not to change.
//however, that is not the case.
function(i);
}
我是否可以使用任何编译器警告,属性,编译器扩展或语言功能来避免这些问题?
答案 0 :(得分:0)
如果希望值为真常量,则可以将其作为模板值参数传递。
template<int i>
void function(){
*side_effect = 123;
}
任何操作都无法修改i
。
这要求输入是编译时常量(并在编译时由编译器验证)。
所以这不起作用:
int main(){
int i = 0;
side_effect = &i;
function<i>();
}
因为i
不是编译时常量。如果我们改为:
int main(){
const int i = 0;
side_effect = &i;
function<i>();
}
function<i>
行有效,但side_effect = &i
不起作用。如果我们添加一个演员:
int main(){
const int i = 0;
side_effect = const_cast<int*>(&i);
function<i>();
}
现在,操作*side_effect = 123
在function
内变为UB。
另一种不要求传入的值是真正的编译时常量的方法是不参考:
void function(int i){
*side_effect = 123;
}
而是采用本地副本(int
或const int
作为参数,具体取决于我们是否希望function
拥有修改i
的权限。 / p>
你想要的全强度版本 - 我们引用外部数据,然后确保外部数据保持不变 - 很容易被证明等同于一般情况下的暂停问题。