Just stumbled over this as I was trying to essentially solve the same problem. It can even be made to work without relying on the rebind
type that is specific to std::allocator
– the only requirement is that the rebound value type is the first template parameter of the respective classes. This is the case for all relevant STL classes (std::vector
, std::set
, std::list
etc. as well as for example std::less
and std::allocator
).
A pre-C++11 solution would look like this:
template
struct rebind;
template class Container, class NewType>
struct rebind, NewType>
{
typedef Container type;
};
template class Container, class NewType>
struct rebind, NewType>
{
typedef Container::type> type;
};
template class Container, class NewType>
struct rebind, NewType>
{
typedef Container::type, typename rebind::type> type;
};
// Continue for more parameters (A, B, C, ...)
C++11 makes it a bit easier:
template
struct rebind;
template class Container, class NewType>
struct rebind, NewType>
{
typedef Container::type...> type;
};
In order to support std::array
, the following can be added:
template class Container, class NewType>
struct rebind, NewType>
{
typedef Container type;
};
The result can be used with just about any STL type:
#include
#include
#include
#include
#include
#include
#include
#include
#include "rebind.h"
// Make it all a bit more compact
#define REBIND_DEMO(container, new_type) \
do { \
container test; \
rebind::type test2; \
std::cout << typeid(test).name() << "\n"; \
std::cout << typeid(test2).name() << "\n"; \
} while (0)
int main()
{
REBIND_DEMO(std::set, double);
REBIND_DEMO(std::list, double);
REBIND_DEMO(std::deque, double);
REBIND_DEMO(std::queue, double);
typedef std::array TestArray;
REBIND_DEMO(TestArray, double);
REBIND_DEMO(std::unordered_set, double);
return 0;
}
Running this and piping the output through c++filt -t
on a Linux system gives you
std::set, std::allocator >
std::set, std::allocator >
std::list >
std::list >
std::deque >
std::deque >
std::queue > >
std::queue > >
std::array
std::array
std::unordered_set, std::equal_to, std::allocator >
std::unordered_set, std::equal_to, std::allocator >