可以将专业化注入 std 命名空间吗?
在这篇关于定义您自己的 扩展的文章中::std::error_code
作者推荐此代码:
namespace std
{
template <>
struct is_error_code_enum<http_error>
: public true_type {};
}
以便实现从您自己的错误常量到系统错误类型的转换。
这合理吗?将东西放入 std
命名空间总是让我感到紧张。有更好的方法来实现目标吗?如果做不到这一切,标准中是否有一部分表明这样做总是可以的?
In this article on defining your own extensions to ::std::error_code
the author recommends this code:
namespace std
{
template <>
struct is_error_code_enum<http_error>
: public true_type {};
}
in order to enable conversions from your own error constants to the system error type.
Is this reasonable? It always makes me nervous to put things into the std
namespace. Is there a better way of accomplishing the goal? Failing all that, is there a part of the standard that says this is always OK to do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,现有 std 类型的特化(对于用户定义的类型)是唯一允许您放入
std
命名空间中的东西,只要特化满足对原始模板的要求。请参阅 C++0x 草案中的 17.6.4.2.1。
当然,新类型、函数重载和其他任何东西都是被禁止的。但允许对现有模板进行专门化。
Yep, specializations (for user-defined types) of existing std types are the only thing you're allowed to put in the
std
namespace, as long as the specialization meets the requirements for the original template.See 17.6.4.2.1 in the C++0x draft.
New types, function overloads and anything else, of course, is forbidden. But specializations of existing templates is allowed.
这不仅可以——在某些情况下是必要的。你不应该做的是在 std 中定义全新的函数/类/模板。
std::swap
尤其是一种常见且简单的专业化事物。有些类需要这样做以允许有效的交换,基本上是交换私有引用来交换内部,而不是使用默认的临时和分配实现。编辑
ildjarn 的评论提到了 ADL - 参数依赖名称查找 。维基百科页面在“接口”和“批评”部分特别提到了
std::swap
。Stroustrup(特别版)的 13.5.2 节包含一个 std::swap 专门化的示例。引用那句话...
我一直认为这表明
std::swap
的专门化是正确的做法,而且我从来没有足够担心 ADL 来质疑这一点,但“之间可能存在差距”在标准库中使用”和“广泛适用的技术” - 该技术不应该用于专门化std::swap
来处理不在标准库中的类型标准
。也有可能存在风格问题,在特别版首次发布时尚未确定。 AFAIK,Stroustrup 添加了一些额外的附录并应用了一些勘误表,但没有对内容进行实质性修改。
根据 Wikipedia 页面,混合添加专业化和 ADL 存在潜在问题 - 有时您可能会出现歧义,从而阻止任何查找。 仅当您混合使用这两种技术时才会发生这种情况,而且众所周知,ADL 无论如何都会导致语义问题。但这种说法只会导致“根本不使用 ADL”,但 ADL 确实存在是有原因的。
嗯,是的,ADL 的存在是有原因的 - 以便与时间一起使用的非成员函数和运算符与类型一起可见。但是 std::swap 并不与一种特定类型相关联 - 它是通用的,只有特定的专业化与特定类型相关联。如果您希望
std::swap
可见,则需要std
命名空间。 ADL 并不是实现这一目标所必需的,正如维基百科页面指出的那样,ADL 也受到了批评。基本上,这意味着我不知道。我有我的合理化理由。他们不一定同意更广泛的风格规则。当然,此评论证明专门化
std::swap
并不是必要 - 您可以提供自己的单独的swap
并依赖 ADL。也许这是首选。检查后我可能会回来再次编辑。
This isn't just OK - it's essential in some cases. What you shouldn't do is to define entirely new functions/classes/templates within std.
std::swap
in particular is a common and simple thing to specialise. Some classes need to do this to allow efficient swaps, basically swapping private references to exchange internals rather than using the default temporary-and-assignments implementation.EDIT
The comment by ildjarn mentions ADL - Argument Dependent name Lookup. The Wikipedia page specifically mentions
std::swap
in the "Interfaces" and "Criticism" section.Section 13.5.2 of Stroustrup (Special Edition) includes an example of specialization of
std::swap
. Quoting from that...I've always read that as indicating that specialization of
std::swap
was the right thing to do, and I've never worried enough about ADL to question that, but it's possible there's a gap between "used in the standard library" and "widely applicable techniques" - that this technique shouldn't be used to specialisestd::swap
to handle types that aren't instd
.It's also possible that there is a style issue that hadn't been decided back when the special edition was first published. AFAIK, Stroustrup has added some extra appendices and applied some errata, but otherwise not substantially revised the content.
Based on the Wikipedia page, there is a potential problem with mixing the addition of specialisations and ADL - sometimes you can get ambiguity preventing any lookup. This only happens if you mix the two techniques, and ADL is know for leading to semantic issues anyway. But that argument only leads to "don't use ADL at all", but ADL does exist for a reason.
Well, yes, ADL exists for a reason - so that non-member functions and operators that work with a time are visible along with the type. But
std::swap
isn't associated with one particular type - it's generic, with only particular specializations being associated with particular types. If you wantstd::swap
to be visible, you want thestd
namespace. ADL isn't necessary to make that work and, as the Wikipedia page points out, there are criticisms of ADL.What this means is, basically, that I don't know. I have my rationalisations. They don't necessarily agree with more widespread style rules. Certainly this comment proves that it's not essential to specialise
std::swap
- you can supply your own separateswap
and rely on ADL instead. Maybe that's preferred.I'll probably come back and edit again after I've checked.