【发布时间】:2014-07-02 18:40:40
【问题描述】:
在 current draft standard 的 17.6.4.2.1/1 和 17.6.4.2.1/2 中,对用户注入 namespace std 的特化设置了限制。
C 的行为 ++ 如果程序向命名空间添加声明或定义,则程序未定义 性病 或到一个 命名空间内的命名空间 性病 除非另有规定。程序可以添加模板特化 用于命名空间的任何标准库模板 性病 仅当声明依赖于用户定义类型 并且专业化满足原始模板的标准库要求并且没有明确 禁止。
我找不到在标准中定义短语用户定义类型的位置。
我听说的一个选项是,不是std::is_fundamental 的类型是用户定义的类型,在这种情况下std::vector<int> 将是用户定义的类型。
另一种答案是用户定义的类型是用户定义的类型。由于用户不定义std::vector<int>,并且std::vector<int> 不依赖于用户定义的任何类型,std::vector<int> 不是用户定义的类型。
这种影响的一个实际问题是“您能否将 std::hash 的专用化 std::tuple<Ts...> 注入 namespace std?能够这样做有点方便 - 替代方法是创建另一个命名空间,我们递归地构建我们的std::tuple 的散列(可能还有std 中不支持hash 的其他类型),并且当且仅当我们未能在该命名空间中找到散列时,我们才回退到std。
但是,如果这是合法的,那么如果标准将 std::tuple 的 hash 特化添加到 namespace std,那么已经特化它的代码将被破坏,从而有理由不在未来。
虽然我在谈论 std::vector<int> 作为一个具体的例子,但我想问一下 std 中定义的类型是否曾经是 用户定义的类型 。第二个问题是,即使不是,std::tuple<int> 可能会在用户使用时成为 用户定义类型(这会变得很棘手:如果 std 内部的某些内容定义了 std::tuple<int>,会发生什么情况,并且您将hash 部分专业化为std::tuple<Ts...>)。
目前有一个open defect解决这个问题。
【问题讨论】:
-
不是指程序员定义的类型吗? C++ 规范中尚不存在的类型?
-
@Robert 不,至少从历史上看不是。从历史上看,UDT 是任何非基本类型,即除枚举和内置类型以外的任何类型,例如
int、char等。但我同意这使得这里引用的上下文中的用法很奇怪。 -
是的,这基本上是我的理解。您可以使用
class或struct定义的任何内容。 -
@Robert 算了,脑子放个屁。我在考虑(非)POD,而不是 UDT。
-
BTW:我已经多次看到这种类型的问题,我一直想知道为什么“用户定义类型”的定义受到质疑,而不是简单地质疑 17.6.4.2.1 中的限制是否简单需要修复(通过扩展措辞以不仅仅依赖 UDT)
标签: c++ c++11 language-lawyer template-specialization c++14