库函数参数不是const时该怎么办

时间:2019-01-08 21:09:40

标签: c++ const

我的大多数代码库都是不可变的;但是,由于语言设计的怪异,我无法标记变量const

在大多数情况下,尤其是在与C代码互操作时,我发现未标记为const的函数参数,即使它们确实没有修改它们。 fts_open(...)就是这样一个例子。此时,编译器迫使我从代码的大部分内容中繁琐地删除const限定符,从而消除了它提供的安全性。

一个简单的解决方案是使用-fpermissive进行编译,但这与我的意图完全相反。

除了重写曾经编写的每个C库之外,我该怎么做才能仍然依靠编译器来获得好处?

即这种类型的代码不起作用:

void function(immutable_type const &param)
{
    char const * const fts_arg[2]{std::data(param.path), nullptr};
    FTS *tree = fts_open(fts_arg, FTS_OPTIONS, nullptr);
    ...
}

此时,我必须:

  • fts_args变量中删除const。
  • 从功能参数中删除const。
  • 从数据类型定义内的path中删除const。
  • 从要传递给function的变量中删除const。
  • 从整个通话链中递归删除const

谢谢。 :)

1 个答案:

答案 0 :(得分:4)

这正是const_cast的用途。如果您绝对知道某个函数不会更改指向/引用的对象,那么即使引用了const对象,也可以const_cast除去指针/引用的常量以将其传递给该函数

  

不是通过const未定义行为进行const_casting吗?

不。 const_cast本身从来都不是UB。但是修改const对象是。因此,如果您不能证明采用非常量指针/引用的函数不会修改该对象,那么将const_cast ed引用传递给该函数是不安全的。

还要考虑将来是否可以更改实现以使用非常量性。


如果无法证明不会对非常量引用/指向的对象进行修改,则可以对包装函数的常量引用参数进行本地复制。此副本的开销可能很小(int)也可能很小(长std::vector)。

如果您不能证明对象不会被修改,并且复制是昂贵的(或不可能的),那么作为最后的选择,您必须摆脱自己参数的常数性(并在调用中传播更改)链)。或在实现中使用其他API。