Interest on container rebind

99 views
Skip to first unread message

Vicente J. Botet Escriba

unread,
May 22, 2013, 6:27:06 PM5/22/13
to std-pr...@isocpp.org
Hi,

I need to transform a vector<optional<T>> into a optional<vector<T>> in
order to implement the following function

optional<vector<T>>
if_all(vector<optional<T>> const& c);

But also to transform set<optional<T>> into optional<set<T>>.

I would like to do it only once with a function

template <typename C>
//requires IsOptional(ValueType(C))
optional<???> if_all(C const& c);

If STL containers provided rebind as Allocators does it would be
possible to define the preceding function as

template <typename C>
//requires IsOptional(ValueType(C))
optional<C::rebind<typename C::value_type::value_type>::other>
if_all(C const& c);

Is there another way to do this without modifying the standard?
Is there an interest on such a possible rebind feature?

Best,
Vicente

Richard Smith

unread,
May 22, 2013, 6:46:20 PM5/22/13
to std-pr...@isocpp.org
Sure. You can write a rebind template and specialize it for each kind of container you want to rebind.

template<typename T, typename U> struct rebind_container_impl;
template<typename T, typename Alloc, typename U> struct rebind_container_impl<std::vector<T, Alloc>, U> {
  using type = std::vector<U, typename std::allocator_traits<Alloc>::template rebind_alloc<U>>;
};
// ...
template<typename T, typename U> using rebind_container = typename rebind_container_impl<T, U>::type;

Vicente J. Botet Escriba

unread,
May 23, 2013, 1:43:03 AM5/23/13
to std-pr...@isocpp.org
Le 23/05/13 00:46, Richard Smith a écrit :
Yes, I know I can do this. But this wouldn't work for a library, as the library doesn't know all the containers.

Best,
Vicente

DeadMG

unread,
May 23, 2013, 4:47:07 PM5/23/13
to std-pr...@isocpp.org
You must use a template template. Check out the automated rebind implementation in allocator_traits.

Vicente J. Botet Escriba

unread,
May 24, 2013, 3:15:43 PM5/24/13
to std-pr...@isocpp.org
Le 23/05/13 22:47, DeadMG a �crit :
> You must use a template template. Check out the automated rebind
> implementation in allocator_traits. --
>
This is exactly what I try to avoid, as I don't want to force the end
user to give me a template template instead of a template container
which can be deduced.

Vicente

DeadMG

unread,
May 24, 2013, 3:49:53 PM5/24/13
to std-pr...@isocpp.org
The user doesn't have to give you a template template. You don't pass allocators as template templates, but allocator_traits::rebind can still automatically implement rebind in the vast majority of cases. Look at it.

Vicente J. Botet Escriba

unread,
May 25, 2013, 9:06:31 AM5/25/13
to std-pr...@isocpp.org
Le 24/05/13 21:49, DeadMG a �crit :
> The user doesn't have to give you a template template. You don't pass
> allocators as template templates, but allocator_traits::rebind can
> still automatically implement rebind in the vast majority of cases.
> Look at it. --
>
I don't get what you try to tell me. Please, could you clarify how
allocator_traits::rebind could help on what I want to do. Could you show
me how to declare my original function

template <typename C>
//requires IsOptional(ValueType(C))
optional<???> if_all(C const& c);

so that it works or all the models of container without modifying the
standard?

Best,
Vicente

Jeffrey Yasskin

unread,
May 25, 2013, 12:17:10 PM5/25/13
to std-pr...@isocpp.org
On Sat, May 25, 2013 at 6:06 AM, Vicente J. Botet Escriba
<vicent...@wanadoo.fr> wrote:
> Le 24/05/13 21:49, DeadMG a écrit :
I think he meant "look at your standard library's implementation of
allocator_traits::rebind in order to answer your question yourself."

Vicente J. Botet Escriba

unread,
May 25, 2013, 1:42:45 PM5/25/13
to std-pr...@isocpp.org
Le 25/05/13 18:17, Jeffrey Yasskin a �crit :
> On Sat, May 25, 2013 at 6:06 AM, Vicente J. Botet Escriba
> <vicent...@wanadoo.fr> wrote:
>> Le 24/05/13 21:49, DeadMG a �crit :
>>
>>> The user doesn't have to give you a template template. You don't pass
>>> allocators as template templates, but allocator_traits::rebind can still
>>> automatically implement rebind in the vast majority of cases. Look at it. --
>>>
>> I don't get what you try to tell me. Please, could you clarify how
>> allocator_traits::rebind could help on what I want to do. Could you show me
>> how to declare my original function
>>
>>
>> template <typename C>
>> //requires IsOptional(ValueType(C))
>> optional<???> if_all(C const& c);
>>
>> so that it works or all the models of container without modifying the
>> standard?
> I think he meant "look at your standard library's implementation of
> allocator_traits::rebind in order to answer your question yourself."
>
Thanks to both for all your help. I was surely looking in the wrong
direction or reading too quickly the posts.
You have never had the solution in face of you and not be able to
getting it at all?

Anyway, IIUC the solution is partial. The default trait of this solution
(Alloc<T, Args>) works only if all the container parameters are types
and the first one is the type to rebind.

template <class C, class T> using rebind = typename
detail::traits_rebind<C, T>::type;

For container having non-type templates, the definition must include its
own rebind, e.g.

template <typename T, size_t N>
struct my_staticaly_bounded_container // std::array?
{
template <class U> using rebind = my_staticaly_bounded_container<U, N>;
};

Is this correct?

If yes, is it wort adding it to the standard so that the users (as me)
can define

template <typename C>
//requires IsOptional(ValueType(C))
optional<rebind<C, typename C::value_type::value_type>> if_all(C
const& c);

Vicente

DeadMG

unread,
May 25, 2013, 1:46:07 PM5/25/13
to std-pr...@isocpp.org
You could simply special-case std::array. However, ultimately, what you are trying to do plain doesn't make sense for all containers- for example, you can't rebind just one type on unordered_map, and even if you did, the hasher and such would be wrong. Your allocator will be incorrect as well if you only rebind the first type- you will have to find which parameter is the allocator and rebind it too.
Reply all
Reply to author
Forward
0 new messages