可以将专业化注入 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::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。也许这是首选。
检查后我可能会回来再次编辑。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
是的,现有 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.