allocator_type get_allocator() const;
概要
アロケータオブジェクトのコピーを取得する。
戻り値
*this
で使用しているアロケータオブジェクトのコピー
備考
*this
で使用しているアロケータオブジェクトは、構築時に設定されたものか、直近の代入時、あるいは、交換時に設定されたもののいずれかである。
例
#include <iostream>
#include <memory>
#include <regex>
#include <type_traits>
template <class T>
struct my_alloc {
using value_type = T;
T* allocate(std::size_t n) { return static_cast<T*>(::operator new(sizeof(T) * n)); }
void deallocate(T* p, std::size_t) noexcept { ::operator delete(static_cast<void*>(p)); }
template <class U>
my_alloc(const my_alloc<U>& b) noexcept : no(b.no) { }
explicit my_alloc(const int _no = 0) : no(_no) { }
int no;
using propagate_on_container_swap = std::true_type;
//using propagate_on_container_copy_assignment = std::true_type;
using propagate_on_container_move_assignment = std::true_type;
my_alloc select_on_container_copy_construction() const { return my_alloc(no + 1); }
};
template <class T1, class T2>
bool operator==(const my_alloc<T1>& a1, const my_alloc<T2>& a2) noexcept
{
return a1.no == a2.no;
}
template <class T1, class T2>
bool operator!=(const my_alloc<T1>& a1, const my_alloc<T2>& a2) noexcept
{
return a1.no != a2.no;
}
template <class BidiIter>
using mymatch = std::match_results<BidiIter, my_alloc<std::sub_match<BidiIter>>>;
int main()
{
mymatch<char*> mm1(my_alloc<std::sub_match<char*>>(1));
// my_alloc は select_on_container_copy_construction を定義しているので、
// コピーコンストラクタではそれを用いてアロケータを取得する。
mymatch<char*> mm2(mm1);
std::cout << mm1.get_allocator().no << ',' << mm2.get_allocator().no << std::endl;
// my_alloc は propagate_on_container_swap を true_type としているので、
// アロケータも swap される。
swap(mm1, mm2);
std::cout << mm1.get_allocator().no << ',' << mm2.get_allocator().no << std::endl;
// my_alloc は propagate_on_container_copy_assignment を true_type としていないので、
// アロケータは copy されない。
mm1 = mm2;
std::cout << mm1.get_allocator().no << ',' << mm2.get_allocator().no << std::endl;
// my_alloc は propagate_on_container_move_assignment を true_type としているので、
// アロケータも move される。
mm1 = std::move(mm2);
std::cout << mm1.get_allocator().no << std::endl;
// move コンストラクタでは、アロケータも無条件に move される。
mymatch<char*> mm3(std::move(mm1));
std::cout << mm3.get_allocator().no << std::endl;
}
出力
1,2
2,1
2,1
1
1
バージョン
言語
- C++11
処理系
- Clang: 3.0 ✅, 3.1 ✅, 3.2 ✅, 3.3 ✅, 3.4 ✅, 3.5 ✅, 3.6 ✅
- GCC: 4.9.0 ✅, 4.9.1 ✅, 5.0.0 ✅
- ICC: ??
- Visual C++: ??
備考
get_allocator
の問題ではないが、GCC(libstdc++) の 4.9.2 までは代入演算子を使用した場合に正しくアロケータを設定しない。