为什么没有标头的不存在是否可以被视为缺陷?
标准库包含一个
标头,该标头(向前)声明包括任何 typedef
的所有流并定义 char_traits
模板,包括专业化。
遗憾的是,没有这样的
标头(向前)声明所有常见的 STL 数据类型和函数,例如 vector
、map
、< code>less、sort
等。更可悲的是,用户代码不允许将此类声明/typedef
添加到 std 命名空间,按照
§17.4.3.1 [lib.reserved.names] p1
:
除非另有说明,否则 C++ 程序向命名空间
std
或命名空间std
内的命名空间添加声明或定义是未定义的。程序可以将任何标准库模板的模板专业化添加到命名空间std
。
是的,这涵盖了(前向)声明的情况,即使这些类型已经存在于标准库中。当然,即使添加这样的声明,大多数(全部?)编译器也会表现得完全正常,但严格来说,从语言律师的角度来说,这是未定义的行为。我发现这对于 typedef
标准容器来说尤其乏味,例如:
// how to forward declare map and string?
typedef std::map<std::string, std::string> Attributes;
现在,这可以被视为缺陷吗?
我的意思是
标头不存在(或者更好,
,也覆盖
)以及对标准库中已存在的声明的禁令。
另外,根据这个问题,如果有一个(转发)完全按照标准的要求声明标准容器、算法和函子/函数,代码应该完全有效(如果不是在 std
中禁止用户声明)命名空间),因为不允许实现添加任何隐藏/默认模板参数。
我问这个问题是因为我正在考虑最终提交一份与此相关的缺陷报告。
The standard library includes an <iosfwd>
header, that (forward) declares all streams including any typedef
s and defines the char_traits
template, including the specializations.
Sadly, there is no such <stlfwd>
header that (forward) declares all the common STL datatypes and functions like vector
, map
, less
, sort
, etc. Even more sadly, user code is not allowed to add such declarations / typedef
s to the std
namespace, as per
§17.4.3.1 [lib.reserved.names] p1
:
It is undefined for a C + + program to add declarations or definitions to namespace
std
or namespaces within namespacestd
unless otherwise specified. A program may add template specializations for any standard library template to namespacestd
.
Yep, that covers the case of (forward) declarations, even if the types already exist in the standard library. Of course, most (all?) compilers will behave perfectly normal even if one adds such declarations, but strictly and language lawyer speaking, it is undefined behaviour. I find this especially tedious for typedef
ing standard containers, like:
// how to forward declare map and string?
typedef std::map<std::string, std::string> Attributes;
Now, can this be considered a defect?
I mean both the non-existence of a <stlfwd>
header (or better, <stdfwd>
, covering <iosfwd>
too) and the ban on declarations already existing in the standard library.
Also, according to this question, if one (forward) declares the standard container, algorithms and functors / functionals exactly as demanded by the standard, the code should be perfectly valid (if it weren't for the ban of user-made declarations in the std
namespace), because implementations aren't allowed to add any hidden/defaulted template parameters.
I am asking this because I'm thinking of eventually submitting a defect report regarding this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
前向声明
less
或sort
或任何其他算法的目的是什么?如果您传递通用算法,它几乎肯定会作为模板类型,根本不需要前向声明。这就只剩下容器类型了。在某些情况下,它们的前向声明肯定是有用的,但我怀疑,由于每个容器定义都相对简单(与 iostream 相比),因此最好只使用完整的包含而不是。例如包括。
What would be the purpose of forward declaring say
less
orsort
or really any other algorithm? If you're passing a general purpose algorithm around it will almost certainly be as a template type and not need a forward declaration at all.That leaves us with the container types. There are definitely cases where forward declarations of them would be useful but I suspect that it was simply decided that as each container definition is relatively simple (compared to iostreams) it would be preferable to just use the full include rather than a <containerfwd> include for example.