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

Yak*_*ont 40 c++ template-specialization language-lawyer c++11 c++14

当前草案的 17.6.4.2.1/1和17.6.4.2.1/2中,标准限制是针对用户注入的专业化namespace std.

如果C++程序向命名空间std或命名空间std中的命名空间添加声明或定义,则它是未定义的,除非另有说明.只有当声明取决于用户定义的类型 并且特化符合原始模板的标准库要求且未明确禁止时,程序才可以将任何标准库模板的模板特化添加到命名空间std .

我无法在标准中找到定义用户定义类型的短语.

我听说声称一个选项是一个类型,是不是std::is_fundamental是一个用户定义类型,在这种情况下std::vector<int>将是一个用户定义的类型.

另一种答案是用户定义的类型用户定义的类型.由于用户未定义std::vector<int>,并且std::vector<int>不依赖于用户定义的任何类型,std::vector<int>因此不是用户定义的类型.

一个实际的问题,这影响是"你可以注入一个专业化的std::hashstd::tuple<Ts...>namespace std如果能够这样做在一定程度上方便-另一种方法是创建另一个命名空间,我们递归构建我们的哈希std::tuple(可能还有其他类型的std没有hash支持),当且仅当我们无法在该命名空间中找到哈希时,我们才会重新开始std.

但是,如果这是合法的,那么如果标准hashstd::tupleto 添加了特殊化namespace std,那么专用它的代码就会被破坏,从而创建一个不再添加此类特化的理由.

虽然我所说的std::vector<int>是一个具体的例子,但我试图询问定义的类型std是否是用户定义的类型.次要问题是,就算没有,也许std::tuple<int>成为一个用户定义类型用户使用时(这得到滑:那么,什么会发生,如果里面的东西std定义std::tuple<int>,你局部专门hashstd::tuple<Ts...>).


目前这个问题存在缺陷.

Dan*_*rey 33

Stroustrup教授非常清楚,任何非内置类型都是用户定义的.请参阅使用C++编程原理和实践中第9.1节的第二段.

他甚至特意将"标准库类型"称为用户定义类型的示例.换句话说,用户定义的类型是任何复合类型.

资源

文章明确提到不是每个人似乎都同意,但这是恕我直言,主要是一厢情愿的想法,而不是标准(和Stroustrup教授)实际上说的是什么,只有一些人想要读到它.

  • TC++ PL 4th edition(2014),p139"标准库提供了许多用户定义的类型." - 同一页面:"枚举和类被称为*用户定义类型*,因为它们必须由用户定义,而不是在没有先前声明的情况下可用,基本类型的方式." (6认同)

Jon*_*ely 16

当第17条说,"用户自定义",它的意思是"在标准中定义的类型"这样std::vector<int>不是用户定义的,也不是std::string,所以你不能专注std::vector<int>std::vector<std::string>.另一方面,struct MyClass用户定义,因为它不是标准中定义的类型,所以你可以专门化std::vector<MyClass>.

这与第1-16条中使用的"用户定义"的含义不同,这种差异令人困惑和愚蠢.有一个缺陷报告,有一些讨论记录,基本上说"是的,图书馆使用错误的术语,但我们没有更好的术语".

所以你的问题的答案是"它取决于".如果您正在与C++编译器实现者或核心语言专家std::vector<int>交谈,那么肯定是用户定义的类型,但如果您正在与标准库实现者交谈,则不是.更确切地说,它不是用于17,6.4.2.1目的的用户定义.

一种看待它的方法是,就核心语言而言,标准库是"用户代码".但是标准库对"用户"有不同的看法,并认为自己是实现的一部分,只有不属于库的东西才是"用户定义的".

编辑:我建议更改库子句使用新术语"程序定义",这意味着在程序中定义的东西(与标准中定义的UDT相反,例如std::string).


Nik*_*iou 7

由于用户未定义std::vector<int>,并且std::vector<int>不依赖于用户定义的任何类型,std::vector<int>因此不是用户定义的类型.

逻辑相反的观点是,用户定义std::vector<int>.您看到的std::vector是一个类模板,因此在二进制代码中没有直接表示.

从某种意义上说,它通过一个类型的实例化获得二进制表示,因此声明一个std::vector<int>对象的动作就是给模板提供"灵魂"(原谅措辞).在没有人使用std::vector<int>此数据类型的程序中不存在.

在另一方面,下面的相同的参数,std::vector<T>不是用户定义的类型,它甚至不是一个类型,它不存在; 只有当我们想要(实例化一个类型)时,它才会强制建立一个结构,但在此之前我们只能在结构,设计,属性等方面争论它.

注意

上面的论点(关于模板不是代码,但......代码的好模板)可能看起来有点肤浅,但从Mayer在A. Alexandrescu的书" Modern C++ Design"中的介绍中得出了它的逻辑.那里的相对引用如下:

最终,Andrei将注意力转向了流行语言习语和设计模式的基于模板的实现的开发,尤其是GoF [*]模式.这导致了与Patterns社区的短暂冲突,因为他们的一个基本原则是模式无法用代码表示.一旦很明显Andrei自动生成模式实现而不是尝试自己编码模式,那个异议就被删除了,我很高兴看到Andrei和其中一个GoF(John Vlissides)在C++报告的两个专栏上合作专注于安德烈的工作.