开发者

Is it OK to inject a specialization into the std namespace?

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 stand开发者_JAVA百科ard that says this is always OK to do?


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜