On 16/03/2016 13:31, Phil Bouchard wrote:
On 03/15/2016 07:25 PM, Glen Fernandes wrote:
You mentioned a while back that you preferred: p.reset(new X(args...)); because it was intuitive, and in your opinion more intuitive than: p = f<X>(args...);
Nobody would have any issue with that. But people would certainly have issue with: Y::Z b(a); p = new (b) Q(b, args...); compared to p = g<X>(a, args...);
Well first if you have a as an r-value: p = g<X>(a, args...)
That's an lvalue, not an rvalue.
That means the allocator parameter must be constant: g<X>(Allocator const &, arg...)
If it's constant it won't be able to change its internal state. I thought that was the purpose of having instantiable allocators?
There's no need for (and no reason for) the allocator to be a const reference.
I can write a wrapper function for: p1 = new (a1) node(a1, 1, 'a');
But not for the declaration of the allocator: boost::node::allocator_type a1(n1, m1);
Why? Because you allocate node<U>s, not Us. I could write some node_traits<> helper:
template
{ typedef typename boost::node ::allocator_type allocator_type; }; So that the declaration becomes: boost::node_traits::allocator_type a1(n1, m1);
But that's all I can do.
Admittedly I'm not familiar with the changes to allocators in C++11 yet, but C++03 allocators support accepting an allocator (even a stateful one) of one type and then using it to make allocations of a different type, via rebind and a templated constructor. std::list and friends use that functionality extensively.