Something very odd turned up during the thread sanitising of proposed boost::concurrent_unordered_map and is recounted at this blog post. In short, bucket_type looks like this:
struct bucket_type_impl
{
spinlock<unsigned char> lock; // = 2 if you need to reload the bucket list
atomic<unsigned> count; // count is used items in there
std::vector<item_type, item_type_allocator> items;
bucket_type_impl() : count(0), items(0) { }
...
Yet the thread sanitiser claims that there is a race between the construction of a bucket_type and its first use, specifically when the count atomic is loaded from. It turns out that if you initialise a std::atomic<> via its constructor, that initialisation is not atomic and therefore the memory location is not atomically released and therefore not visible to other threads, which is counterintuitive given it's an atomic, and that most atomic operations default to memory_order_seq_cst. You must therefore explicitly do a release store after construction to initialise the atomic with a value visible to other threads.
Is there some extremely pressing reason why std::atomic with a value consuming constructor does not initialise itself with release semantics? If not, I think this is a library defect.
Edit: Jonathan's answer is the better for the history as to why, but ecatmur's answer links to Alastair's defect report on the matter, and how it was closed by simply adding a note to say construction offers no visibility to other threads. I'll therefore award the answer to ecatmur. Thanks to all who replied, I think the way is clear to ask for an extra constructor, it will at least stand out in the documentation that there is something unusual with the value consuming constructor.
Edit 2: I ended up raising this as a defect in the C++ language with the committee, and Hans Boehm who chairs the Concurrency part feels this is not an issue for the following reasons:
No present C++ compiler in 2014 treats consume as different to acquire. As you will never, in real world code, pass an atomic to another thread without going through some release/acquire, the initialisation of the atomic would be made visible to all threads using the atomic. I think this fine until compilers catch up, and before that the Thread Sanitiser will warn on this.
If you're doing mismatched consume-acquire-release like I am (I am using a release-inside-lock/consume-outside-lock atomic to speculatively avoid a release-acquire spinlock where it was unnecessary) then you're a big enough boy to know you must manually store release atomics after construction. That is probably a fair point.