8

This question has also been submitted to Usenet, where it is more appropriate, but this is a larger and more reliable forum.

std::allocator::construct is defined to forward its argument parameter pack to object construction using parentheses, a.k.a. direct-initialization.

If it used braces, a.k.a. uniform initialization, we could initialize aggregate data types from functions such as std::make_shared and container::emplace. Also, it would be acceptable to put the contents of an initializer list into the argument list of such a function, solving the problem of initializer_list type deduction under forwarding.

Was this alternative considered and rejected? Is it too late to switch in a future standard? It seems this would be a breaking change, but not a particularly heinous one.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421

1 Answers1

10

I don't know what the SC considered, but keep in mind that uniform initialization doesn't really 'work' in generic contexts (barring value construction*). Consider this attempt:

template<typename T, typename... Args>
T
make(Args&&... args)
{
    return T { std::forward<Args>(args)... };
}

You get:

assert( make<std::vector<int>>(10, 0).size() == 2 );
assert( std::vector<int>(10, 0).size() == 10 );

and this doesn't compile:

make<std::vector<int*>>(10u, 0);

whereas this does:

std::vector<int*>(10u, 0);

If the particular interaction between perfect forwarding and initializer lists that causes this was formalized soon enough I could see the SC not wanting to restart from scratch.

(*): T {} is fine even in generic contexts.

Luc Danton
  • 34,649
  • 6
  • 70
  • 114
  • Bah, the Do The Right Thing construct. I haven't been bitten by that one yet. Still it would be nice to have an alternative. The Standard requires that `std::is_constructible::value` be `true` for the arguments of `construct`; direct initialization could be a fallback provided by an implementation under the umbrella of UB. – Potatoswatter Oct 19 '11 at 11:12
  • @Potatoswatt Since that trait would return `true` iff the type is constructible using direct initialization, I think you mean that the fallback be uniform initialization. An interesting idea, that's backward compatible with the current rules. – Luc Danton Oct 19 '11 at 11:18