简体   繁体   English

std :: vector <T>是一个“用户定义的类型”吗?

[英]Is std::vector<T> a `user-defined type`?

In 17.6.4.2.1/1 and 17.6.4.2.1/2 of the current draft standard restrictions are placed on specializations injected by users into namespace std . 当前草案的 17.6.4.2.1 / 1和17.6.4.2.1 / 2中, 标准限制被放置在用户注入namespace std专门化中。

The behavior of a C ++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. 如果C ++程序向命名空间std或命名空间std中的命名空间添加声明或定义,则它是未定义的,除非另有说明。 A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited. 只有当声明取决于用户定义的类型并且特化符合原始模板的标准库要求且未明确禁止时,程序才可以将任何标准库模板的模板特化添加到命名空间std。

I cannot find where in the standard the phrase user-defined type is defined. 我无法在标准中找到定义用户定义类型的短语。

One option I have heard claimed is that a type that is not std::is_fundamental is a user-defined type , in which case std::vector<int> would be a user-defined type . 我听过的一个选项是,不是std::is_fundamental 类型用户定义的类型 ,在这种情况下, std::vector<int>将是用户定义的类型

An alternative answer would be that a user-defined type is a type that a user defines. 另一种答案是用户定义的类型用户定义的类型 As users do not define std::vector<int> , and std::vector<int> is not dependent on any type a user defines, std::vector<int> is not a user-defined type . 由于用户没有定义std::vector<int> ,并且std::vector<int>不依赖于用户定义的任何类型,因此std::vector<int>不是用户定义的类型

A practical problem this impacts is "can you inject a specialization for std::hash for std::tuple<Ts...> into namespace std ? Being able to do so is somewhat convenient -- the alternative is to create another namespace where we recursively build our hash for std::tuple (and possibly other types in std that do not have hash support), and if and only if we fail to find a hash in that namespace do we fall back on std . 这个影响的一个实际问题是“你可以为std::tuple<Ts...> std::hash注入一个特殊化的namespace std吗?能够做到这一点有点方便 - 另一种方法是创建另一个命名空间我们递归地为std::tuple (以及可能没有hash支持的std中的其他类型)构建我们的散列,当且仅当我们在该命名空间中找不到散列时,我们才会回到std

However, if this is legal, then if and when the standard adds a hash specialization for std::tuple to namespace std , code that specialized it already would be broken, creating a reason not to add such specializations in the future. 但是,如果这是合法的,那么如果当标准增加了一个hash专业化的std::tuplenamespace std ,即专门它已经将被打破代码,创建一个没有理由在未来添加此类专业。

While I am talking about std::vector<int> as a concrete example, I am trying to ask if types defined in std are ever user-defined type s. 虽然我在谈论std::vector<int>作为具体示例,但我试图询问std定义的类型是否是用户定义的类型 A secondary question is, even if not, maybe std::tuple<int> becomes a user-defined type when used by a user (this gets slippery: what then happens if something inside std defines std::tuple<int> , and you partial-specialize hash for std::tuple<Ts...> ). 第二个问题是,即使没有,也许std::tuple<int>用户使用时会变成用户定义的类型 (这会变得很滑:如果std某些内容定义了std::tuple<int> ,那么会发生什么你为std::tuple<Ts...>部分专门化hash


There is currently an open defect on this problem. 目前这个问题存在缺陷

Prof. Stroustrup is very clear that any type that is not built-in is user-defined . Stroustrup教授非常清楚,任何非内置类型都是用户定义的 See the second paragraph of section 9.1 in Programming Principles and Practice Using C++. 请参阅使用C ++编程原理和实践中第9.1节的第二段。

He even specifically calls out “standard library types” as an example of user-defined types. 他甚至特意将“标准库类型”称为用户定义类型的示例。 In other words, a user-defined type is any compound type. 换句话说,用户定义的类型是任何复合类型。

Source 资源

The article explicitly mentions that not everyone seems to agree, but this is IMHO mostly wishful thinking and not what the standard (and Prof. Stroustrup) are actually saying, only what some people want to read into it. 文章明确提到不是每个人似乎都同意,但这是恕我直言,主要是一厢情愿的想法,而不是标准(和Stroustrup教授)实际上说的是什么,只有一些人想要读到它。

When Clause 17 says "user-defined" it means "a type not defined in the standard" so std::vector<int> is not user-defined, neither is std::string , so you cannot specialize std::vector<int> or std::vector<std::string> . 当第17条说“用户定义”时,它意味着“未在标准中定义的类型”,因此std::vector<int> 不是用户定义的,也不是std::string ,所以你不能专门化std::vector<int>std::vector<std::string> On the other hand, struct MyClass is user-defined, because it's not a type defined in the standard, so you can specialize std::vector<MyClass> . 另一方面, struct MyClass是用户定义的,因为它不是标准中定义的类型,因此您可以专门化std::vector<MyClass>

This is not the same meaning of "user-defined" used in clauses 1-16, and that difference is confusing and silly. 这与第1-16条中使用的“用户定义”的含义不同,这种差异令人困惑和愚蠢。 There is a defect report for this, with some discussion recorded that basically says "yes, the library uses the wrong term, but we don't have a better one". 有一个缺陷报告 ,有一些讨论记录,基本上说“是的,图书馆使用错误的术语,但我们没有更好的术语”。

So the answer to your question is "it depends". 所以你的问题的答案是“它取决于”。 If you're talking to a C++ compiler implementor or a core language expert, std::vector<int> is definitely a user-defined type, but if you're talking to a standard library implementor, it is not. 如果您正在与C ++编译器实现者或核心语言专家交谈,那么std::vector<int>肯定是用户定义的类型,但如果您正在与标准库实现者交谈,则不是。 More precisely, it's not user-defined for the purposes of 17,6.4.2.1 . 更确切地说,它不是用于17,6.4.2.1目的的用户定义。

One way to look at it is that the standard library is "user code" as far as the core language is concerned. 一种看待它的方法是,就核心语言而言,标准库是“用户代码”。 But the standard library has a different idea of "users" and considers itself to be part of the implementation, and only things that aren't part of the library are "user-defined". 但是标准库对“用户”有不同的看法,并认为自己是实现的一部分,只有不属于库的东西才是“用户定义的”。

Edit: I have proposed changing the library Clauses to use a new term, "program-defined", which means something defined in your program (as opposed to UDTs defined in the standard, such as std::string ). 编辑:我建议更改库子句使用新术语“程序定义”,这意味着在程序中定义的东西(与标准中定义的UDT相反,例如std::string )。

As users do not define std::vector<int> , and std::vector<int> is not dependent on any type a user defines, std::vector<int> is not a user-defined type. 由于用户没有定义std::vector<int> ,并且std::vector<int>不依赖于用户定义的任何类型,因此std::vector<int>不是用户定义的类型。

The logical counter argument is that users do define std::vector<int> . 逻辑计数器参数是用户确实定义了std::vector<int> You see std::vector is a class template and as such has no direct representation in binary code. 您看到std::vector是一个类模板 ,因此在二进制代码中没有直接表示。

In a sense it gets it binary representation through the instantiation of a type, so the very action of declaring a std::vector<int> object is what gives "soul" to the template (pardon the phrasing). 从某种意义上说,它通过类型的实例化获得二进制表示,因此声明std::vector<int>对象的动作就是给模板提供“灵魂”(原谅措辞)。 In a program where noone uses a std::vector<int> this data type does not exist. 在没有人使用std::vector<int>的程序中,此数据类型不存在。

On the other hand, following the same argument, std::vector<T> is not a user defined type, it is not even a type, it does not exist; 另一方面,遵循相同的参数, std::vector<T> 不是用户定义的类型,它甚至不是类型,它不存在; only if we want to (instantiate a type), it will mandate how a structure will be layed out but until then we can only argue about it in terms of structure , design , properties and so on. 只有当我们想要(实例化一个类型)时, 它才会强制建立一个结构,但在此之前我们只能在结构设计属性等方面争论它。

Note 注意

The above argument (about templates being not code but ... well templates for code) may seem a bit superficial but draws it's logic, from Mayer's introduction in A. Alexandrescu's book Modern C++ Design . 上面的论点(关于模板不是代码,但......代码的好模板)可能看起来有点肤浅,但从Mayer在A. Alexandrescu的书“ Modern C ++ Design”中的介绍中得出了它的逻辑。 The relative quote there, goes like this : 那里的相对引用如下:

Eventually, Andrei turned his attention to the development of template-based implementations of popular language idioms and design patterns, especially the GoF[*] patterns. 最终,Andrei将注意力转向了流行语言习语和设计模式的基于模板的实现的开发,尤其是GoF [*]模式。 This led to a brief skirmish with the Patterns community, because one of their fundamental tenets is that patterns cannot be represented in code. 这导致了与Patterns社区的短暂冲突, 因为他们的一个基本原则是模式无法用代码表示。 Once it became clear that Andrei was automating the generation of pattern implementations rather than trying to encode patterns themselves , that objection was removed, and I was pleased to see Andrei and one of the GoF (John Vlissides) collaborate on two columns in the C++ Report focusing on Andrei's work. 一旦很明显Andrei自动生成模式实现而不是尝试自己编码模式 ,那个反对意见就被删除了,我很高兴看到Andrei和其中一个GoF(John Vlissides)在C ++报告中的两个专栏上进行合作专注于安德烈的工作。

The draft standard contrasts fundamental types with user-defined types in a couple of (non-normative) places. 标准草案将基本类型与用户定义类型对比在几个(非规范)位置。

The draft standard also uses the term "user-defined" in other contexts, referring to entities created by the programmer or defined in the standard library. 标准草案还在其他上下文中使用术语“用户定义”,指的是程序员创建的标准库中定义的实体。 Examples include user-defined constructor, user-defined operator and user-defined conversion. 示例包括用户定义的构造函数,用户定义的运算符和用户定义的转换。

These facts allow us, absent other evidence, to tentatively assume that the intent of the standard is that user-defined type should mean compound type, according to historical usage. 根据历史用法,这些事实使我们在没有其他证据的情况下暂时假设标准的意图是用户定义的类型应该是复合类型。 Only an explicit clarification in a future standard document can definitely resolve the issue. 只有未来标准文件中的明确说明才能解决问题。

Note that the historical usage is not clear on types like int* or struct foo* or void(*)(struct foo****) . 请注意,类似int*struct foo*void(*)(struct foo****)等类型的历史用法并不明确。 They are compound, but should they (or some of them) be considered user-defined? 它们是复合的,但它们(或其中一些)是否应被视为用户定义的?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM