内部的な型のアロケート
C++11で導入されたライブラリのいくつかは、内部で使用する型のオブジェクトをアロケートするアロケータを、公開インタフェースとして要求します。
たとえば、std::function<R(Args...)>
:
template <class F, class Alloc> void function::assign(F&& f, const Alloc& alloc);
std::function
は、関数オブジェクト型F
を内部的にアロケートします。
たとえば、std::shared_ptr<T>
:
template <class Y, class Deleter, class Alloc> shared_ptr(Y* p, Deleter d, Alloc a);
std::shared_ptr
は、内部で参照カウンタをアロケートします。参照カウンタの型はprivate
なので、ユーザーは型名がわかりません。
こういうインタフェースに対しては、てきとうな要素型のアロケータオブジェクトを渡します。std::allocator<int>
でもstd::allocator<MyClassType>
でもかまいません。
そして、これらの関数の内部で、適切な要素型にアロケータをrebindされ、それらの要素型のオブジェクトがアロケートされます。
std::function
の例:
#include <iostream> #include <functional> int ident(int x) { return x; } int main() { std::function<int(int)> f; // 関数とアロケータを代入。 // // ※ここではint型を対象とするアロケータを渡しているが、 // 内部で適切な関数の型にrebindして使われる。 f.assign(ident, std::allocator<int>()); int result = f(1); std::cout << result << std::endl; }
std::shared_ptr
の例:
#include <iostream> #include <memory> int main() { std::shared_ptr<int> p = { new int(3), std::default_delete<int>(), std::allocator<void>() }; std::cout << *p << std::endl; }
これらの関数の仕様上、rebindすることは明確に記載されてはいないのですが、Allocator requirementsを満たすアロケータ型を要求してるという点と、rebindを使うしか方法がない、という可能性の検討の結果、rebindを使うということがわかります。
std::function
とstd::shared_ptr
のほか、std::promise
もアロケータをrebindします。std::promise
は内部的にstd::shared_ptr
を作りますが、そのことが公開インタフェースにはなっていないからです。