将特化注入std命名空间是否可以?

Omn*_*ous 16 c++ template-specialization c++11

本文中,关于::std::error_code为作者定义自己的扩展,建议使用以下代码:

namespace std
{
  template <>
  struct is_error_code_enum<http_error>
    : public true_type {};
}
Run Code Online (Sandbox Code Playgroud)

为了实现从您自己的错误常量到系统错误类型的转换.

这合理吗?将东西放入std命名空间总是让我感到紧张.有没有更好的方法来实现目标?如果做不到这一点,标准的一部分是否可以做到这一点?

jal*_*alf 23

是的,只要专业化符合原始模板的要求,现有std类型的特化(对于用户定义类型)是唯一允许放入std命名空间的东西.

请参阅C++ 0x草案中的17.6.4.2.1.

当然,禁止使用新类型,功能过载和其他任何东西.但是允许对现有模板进行特化.


Ste*_*314 8

这不仅仅是好的 - 在某些情况下这是必不可少的.你不应该做的是在std中定义全新的函数/类/模板.

std::swap特别是专业化的常见而简单的事情.有些类需要这样做以允许有效的交换,基本上交换私有引用到交换内部,而不是使用默认的临时和赋值实现.

编辑

ildjarn的评论提到了ADL - Argument Dependent name Lookup.维基百科页面std::swap在"界面"和"批评"部分特别提到.

Stroustrup(特别版)的第13.5.2节包括一个专业化的例子std::swap.引用那个......

这些特殊化less()swap()用于标准库(16.3.9,20.3.16).此外,它们是广泛适用的技术的例子.

我一直都认为这表明专业化std::swap是正确的事情,而且我从来没有担心ADL会对此提出质疑,但是"标准库中使用"和"广泛适用的技术"之间可能存在差距. " - 应该使用这种技术来专门std::swap处理不在的类型std.

特殊版本首次发布时,还可能存在尚未确定的样式问题.AFAIK,Stroustrup已经添加了一些额外的附录并应用了一些勘误表,但在其他方面没有对内容进行实质性修改.

根据维基百科的页面上,还有就是用混合除了专业化和ADL的一个潜在的问题-有时你可以得到含糊防止任何查找.只有在混合使用这两种技术时才会发生这种情况,并且ADL知道无论如何都会导致语义问题.但是这个论点只会导致"根本不使用ADL",但ADL确实存在是有原因的.

嗯,是的,ADL的存在是有原因的 - 因此,使用时间的非成员函数和运算符与类型一起可见.但是std::swap与一种特定类型无关 - 它是通用的,只有特定的特殊化与特定类型相关联.如果要std::swap显示,则需要std命名空间.ADL没有必要做到这一点,正如维基百科页面指出的那样,有批评ADL.

基本上,这意味着我不知道.我有理性主义.他们不一定同意更广泛的风格规则.当然,这个评论证明了专业化并不是必需的std::swap - 你可以提供自己独立的swap,而不是依赖ADL.也许这是首选.

在我检查完之后,我可能会再回来编辑.

  • `std :: swap`应该**不是专门的或重载的 - 相反,应该将`swap` free函数放在与被交换类型相同的命名空间中,让ADL完成其余的工作. (2认同)