什么时候从函数的参数化中省略常量是安全的?

When is it safe to leave out a const from a function's parametrization?

提问人:Gyula Sámuel Karli 提问时间:10/17/2022 最后编辑:SebastianGyula Sámuel Karli 更新时间:10/17/2022 访问量:90

问:

很多时候,我编写C++函数时,我似乎比其他人使用更多的修饰符。const

例如,我编写 Excel .xlsx 文件并使用 LibXL 库,文档提到了这样的函数:

bool writeNum(int row, int col, double value, Format* format = 0)

我碰巧继承了这个函数,我的签名是这样的:

bool XLAPIENTRY writeNum(const int row, const int col, const double value, IFormatT<wchar_t> * format = 0);

请注意行和列的 s。const int

问题:离开 s 安全吗?(对于指针来说,省略 const 作为指针是危险的,但做一些本地副本的事情并不那么危险)。请注意,包含 writeNum 函数的原始标头也没有提到 const-ing s 。为什么这里省略了修饰符?constintintintconst

C++ 常量 参数传递 函数签名

评论

1赞 john 10/17/2022
省略整数(和双精度)是安全的const
0赞 Botje 10/17/2022
另请参阅讨论,该讨论现在将因“征求意见”而结束。
3赞 john 10/17/2022
请注意,和 是两个不同的声明。在第一个中,指针是常量,在第二个中,指针是常量。在第二种情况下,省略 也是安全的,就像 ints 一样。const int* ptrint* const ptrintconst
0赞 Sebastian 10/17/2022
此处使用有几个相关目的,在 C++ 中没有明确单独注释。1)这是与来电者的合同。这仅对引用和指针(在 之前)重要,而对按值划分的非指针参数不重要。2)参数在被调用函数中的作用类似于局部变量。使用实际上是一个实现细节,它已经泄漏到函数签名中。这与非指针值参数和带有 before 的指针相关。3) 也可以是优化器的性能提示。constconst*const*constconst
0赞 Sebastian 10/17/2022
在您的情况下,1) 不适用于 s - 它们是值参数。3) 可以毫不费力地复制 s,它们通常小于 64 位指针,因此在内部使用 const 引用(这可能是对较大对象的优化)会更慢。所以只剩下 2) 了,这是函数的实现细节。现在有一些想法(和建议)将常量值参数的签名视为非常量值参数,但这些想法(和建议)可能无处可去,以保持向后兼容性。intint

答:

8赞 HolyBlackCat 10/17/2022 #1

声明(与定义相反)中,参数上的顶级1 常量不起作用。可以说,它是函数的实现细节,不应该出现在声明中(它增加了混乱,但不会为调用者提供任何新信息)。

请注意,和 是顶级常量,而 和 不是,因此后者不能删除它。const int xint *const xconst int *const int &const

定义中,您可以包含 if it 作为函数的实现者(这样您就不会意外更改参数)。const


1 “顶级常量”的意思是“实际常量”,而不是仅仅是指向常量的指针。您可以使用 检查此属性。std::is_const_v

例如:

  • std::is_const_v<const int> == true (常量整数)
  • std::is_const_v<const int *> == false (指向 const 整数的非常量指针)
  • std::is_const_v<int *const> == true (指向非常量整数的 const 指针)
  • std::is_const_v<const int **> == false (指向 const 整数的非常量指针)
  • std::is_const_v<int *const *> == false (指向 const 的 non-const 指针 指向非 const 整数的指针)
  • std::is_const_v<int **const> == true (指向非非常量整数的 const 指针)

评论

0赞 Gyula Sámuel Karli 10/17/2022
哼。据我了解,顶级 const 是一个 const 指针,而低级 const 是一个常量值。1. 对吗?2. 如果是这样,为什么“const in x”是顶级的东西(如果“x”在这里表示参数的名称)。
0赞 HolyBlackCat 10/17/2022
@GyulaSámuelKarli 1.是的。2. 对于非指针类型,只有一个“级别”的恒度,因此它也可以被认为是顶级的。或者,对于 ,有三个可能的地方可以添加(3 个级别),其中只有一个是“顶级”(一个)。int **xconstint **const x
1赞 HolyBlackCat 10/17/2022
@GyulaSámuelKarli 一般来说,如果返回 true,那么它就是顶级常量。 是真的。std::is_const_vstd::is_const_v<const int>
0赞 Gyula Sámuel Karli 10/17/2022
一个幼稚的问题,对于C++业务中的人来说,“顶级”是一个显而易见的东西吗?我认为这应该添加到答案中
0赞 HolyBlackCat 10/17/2022
@GyulaSámuelKarli我希望这是显而易见的,但也许不是。我添加了一个简短的解释。