C++ 在C+中标记为已弃用的函数参数+;14

C++ 在C+中标记为已弃用的函数参数+;14,c++,c++14,deprecated,deprecation-warning,C++,C++14,Deprecated,Deprecation Warning,通过阅读和评论,我注意到它给出了一个例子,可以将特定的函数参数标记为不推荐的,如(摘自文章的示例): 现在我想知道,这样一个特性的好用例是什么?在那篇帖子的评论中,或者在我搜索过的其他地方,似乎没有人有任何线索 编辑: 要查看它的实际应用,有一个可编译的示例想象一下一个实现、使用和维护了多年的库。此库用于多个项目。 如果只是删除该参数,则所有项目都必须在升级到新库版本后立即调整源代码,以便能够再次编译。 如果在参数中添加了一个默认值,但不再使用该参数,则项目仍将编译而不进行任何更改,但没有人会注

通过阅读和评论,我注意到它给出了一个例子,可以将特定的函数参数标记为不推荐的,如(摘自文章的示例):

现在我想知道,这样一个特性的好用例是什么?在那篇帖子的评论中,或者在我搜索过的其他地方,似乎没有人有任何线索

编辑:


要查看它的实际应用,有一个可编译的示例

想象一下一个实现、使用和维护了多年的库。此库用于多个项目。
如果只是删除该参数,则所有项目都必须在升级到新库版本后立即调整源代码,以便能够再次编译。
如果在参数中添加了一个默认值,但不再使用该参数,则项目仍将编译而不进行任何更改,但没有人会注意到某些内容已发生了更改,并且可能由该参数控制的某些行为/功能不再起作用


因此,通过将参数标记为已弃用,项目可以编译而不做任何更改,但他们会收到一条警告,说明某些内容已更改,他们应该更改其源代码,因为该参数迟早会消失。

假设您有这样一个函数:

void* allocate(std::size_t sz, void* hint = nullptr) {
    // if you give `hint` it *might* be more efficient
}
然后你决定不再值得花精力去做基于
hint
的事情。所以你会这样做:

void* allocate(std::size_t sz, [[deprecated]] void* hint = nullptr) {
    // `hint` is ignored. The compiler warns me if I use it in the
    // function body accidentally, and people reading the function
    // signature can see that it is probably going to be ignored.
}
这允许库保留相同的签名/ABI(因此您不需要重新编译使用它的内容,遗留代码仍然可以继续使用它而不会造成任何伤害),还可以防止在更改函数时意外再次使用它

但这主要是针对函数的开发人员,而不是函数的用户,以便他们知道为什么会有一个看似“无用”的参数

我还认为这将禁用gcc/clang中带有
-Werror=unused parameter
标志的“unused parameter”警告,但事实并非如此。使用
(void)deprecated_参数
也会发出有关使用不推荐的参数的警告,因此这看起来像是一个bug。如果它确实禁用了unused param警告,那将是
[[deprecated]]

的另一个用例,规则是(广义上)。对于在函数参数中找到的此类声明,它是不被特别允许的

最初的提案也没有提到这样的用例,原始特性的文档也没有提到(我没有检查Clang)

因此,我认为这是一个“意外”,这是允许的,而不是任何人真正认为有用的东西

如Artyer所探索的,记录不推荐的默认参数是否有用?是的,潜在的,模糊的。但正如Artyer也发现的那样,主流编译器实际上并没有对这种用法做出有益的反应


因此,在目前情况下,它没有什么用处,语言功能也不是专门为这种情况设计的。

Hm.我考虑的是默认参数,但gcc没有在
void f([[deprecated]]int n=0)中对任何一条语句发出警告;void g(){f();f(2);}
。它只在函数体中发出警告。正如您所看到的,使用gcc trunk时,警告是在函数内部使用参数时发出的,而不是在调用时发出的,这就是为什么它令人费解的原因。为什么您认为存在用例?也许这是可能的,只是因为没有一个例外是不允许的。@eerorika我不认为有一个用例。完全有可能这个功能只是碰巧在没有任何计划的情况下可用,并且保持它的原样不会有什么害处,但是我很好奇是否真的有用例。但是g++和clang++都只在该函数定义中使用参数时发出警告,而不在对该函数的任何调用时发出警告,它们是否为该参数提供参数。这与您所描述的正好相反。但是无论是clang++还是g++实际上都不会对函数的任何调用发出警告,无论它们是否为
hint
@aschepler Yes提供参数,因为该参数始终以任何方式传递(即使由于默认参数,它隐式位于调用方一侧),这与不推荐使用的整个函数不同。它更像是在函数体中被弃用了,但是调用方并不总是需要关心这一点。这很好。但这并不像清理后删除参数名那样惯用。虽然我可以看到这样一个没有计划的情况是如何发生的,但我认为这不太可能一直没有被注意到。在介绍之后的讨论中有没有提到它?我不认为它“没有被注意到”,我认为你只是第一个关心它的人:P毕竟,我们可以编写很多其他无用的代码,这取决于我们个人。换句话说:为什么要费心在语言中写一条特殊的规则来禁止它呢?我们能从这样的复杂局面中得到什么?这才是问题的关键。
void* allocate(std::size_t sz, [[deprecated]] void* hint = nullptr) {
    // `hint` is ignored. The compiler warns me if I use it in the
    // function body accidentally, and people reading the function
    // signature can see that it is probably going to be ignored.
}