如何防止const&间接改变的论点?

时间:2016-01-07 03:18:20

标签: c++ reference immutability side-effects c++17

是否有可能使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);
}

我是否可以使用任何编译器警告,属性,编译器扩展或语言功能来避免这些问题?

1 个答案:

答案 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 = 123function内变为UB。

另一种不要求传入的值是真正的编译时常量的方法是不参考:

void function(int i){
  *side_effect = 123;
}

而是采用本地副本(intconst int作为参数,具体取决于我们是否希望function拥有修改i的权限。 / p>

你想要的全强度版本 - 我们引用外部数据,然后确保外部数据保持不变 - 很容易被证明等同于一般情况下的暂停问题。