可以将专业化注入 std 命名空间吗?

发布于 11-27 20:17 字数 327 浏览 1 评论 0原文

在这篇关于定义您自己的 扩展的文章中::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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青春有你2024-12-04 20:17:39

是的,现有 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.

美人如玉2024-12-04 20:17:39

这不仅可以——在某些情况下是必要的。你不应该做的是在 std 中定义全新的函数/类/模板。

std::swap 尤其是一种常见且简单的专业化事物。有些类需要这样做以允许有效的交换,基本上是交换私有引用来交换内部,而不是使用默认的临时和分配实现。

编辑

ildjarn 的评论提到了 ADL - 参数依赖名称查找 。维基百科页面在“接口”和“批评”部分特别提到了 std::swap

Stroustrup(特别版)的 13.5.2 节包含一个 std::swap 专门化的示例。引用那句话...

这些 less()swap() 的特化在标准库(16.3.9、20.3.16)中使用。此外,它们是广泛适用的技术的示例。

我一直认为这表明 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...

These specializations of less() and swap() are used in the standard library (16.3.9, 20.3.16). In addition, they are examples of widely applicable techniques.

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 specialise std::swap to handle types that aren't in std.

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 want std::swap to be visible, you want the std 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 separate swap and rely on ADL instead. Maybe that's preferred.

I'll probably come back and edit again after I've checked.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文