是否允许实现将公共成员添加到标准类型?

时间:2014-02-03 22:37:04

标签: c++ c++11 language-lawyer c++14

C ++标准库实现是否允许将公共(和受保护)成员添加到标准类型的接口? N3797 17.6.5.5 [member.functions] / 2说:

  

实现可以在类中声明其他非虚拟成员函数签名:

     

- 通过向成员函数签名添加带默认值的参数; [注意:实现可能不会将具有默认值的参数添加到虚拟,全局或非成员函数。 - 结束记录]

     

- 通过两个或多个具有等效行为的成员函数签名替换具有默认值的成员函数签名;和

     

- 通过为成员函数名称添加成员函数签名。

这是否意味着标准库无法在任何情况下(包括例如保留标识符)添加标准中未提及名称的任何其他公共成员?

一点点解释:这是关于添加签名的文本(我假设只是针对已经定义的函数的新签名,所以没有新的名称)我设法找到标准。还有脚注189,其中说:

  

有效的C ++程序始终调用预期的库成员函数或具有等效行为的函数。实现还可以定义其他成员函数,否则这些函数将不会被有效的C ++程序调用。

所有这些文本都来自[member.functions],所以它显然只是关于成员函数。我的问题更通用,并询问我可能错过的任何参考:标准库实现允许将新的名称添加到标准类型的公共(和/或受保护)接口,无论是数据或功能成员?

2 个答案:

答案 0 :(得分:5)

我相信你的所需内容与脚注189相结合,即:

  

有效的C ++程序始终调用预期的库成员函数或具有等效行为的函数。实现还可以定义其他成员函数,否则这些函数将不会被有效的C ++程序调用。

和部分17.6.5.11 派生类,其中包含:

  

实现可以从具有为实现保留的名称的类派生C ++标准库中的任何类。

但不添加任何限制,即它不会限制访问限定符等...

我们可以看到libstdc++非常有效地使用派生类,例如在stl_vector.h中。虽然我可以看到libstdc++似乎确实避免添加公共数据成员,但这可能更适用于简洁设计。

至少,这看起来不明确,但如果你坚持类似于libstdc++实现风格的东西,你应该是好的。

答案 1 :(得分:2)

我认为阅读脚注189的关键是短语would otherwise not be called by a valid C++ program

请记住,以下划线后跟大写字母(或在任何地方包含两个连续下划线)开头的标识符是为实现保留的。 (第17.6.4.3.2节)

因此,实现可以自由添加以这种方式命名的公共/受保护成员函数。

例如,在libc ++中,std::vector有一个名为__throw_length_error的受保护成员函数