はじめに
c++で数値計算を行う場合、Eigenライブラリを使うことが多いです。Eigenライブラリの使い方は
がコンパクトにまとまっていてわかりやすいでしょう。
しばしばEigenクラスのオブジェクトをSTLコンテナ(std::vector
等)に格納する必要があるのですが、”Fixed-size vectorizable”なEigenクラスをSTLコンテナに格納する場合、特別なアロケータEigen::aligned_allocator<T>
を使用しなければなりません。
使わないとプログラムが途中でクラッシュします。
自動的に適切なアロケータを選択させる
アロケータをテンプレートパラメータとして一々与えるのは面倒ですし、バグの基です。
そこでc++らしくコンテナ要素の型T
に応じて自動的にアロケータを選択するようにします。
追記:GitHub: shohirose/qiita/fixed_size_vectorizableにアップしました。
is_fixed_size_vectorizable.hpp
#include <type_traits>
#include <Eigen/Core>
#include <Eigen/Geometry>
namespace foo {
template <typename T>
struct is_fixed_size_vectorizable : std::false_type {};
// fixed-size vectorizableなEigenクラスに対してテンプレートを特殊化
template <>
struct is_fixed_size_vectorizable<Eigen::Vector2d> : std::true_type {};
// ... 以下同様
} // end namespace foo
allocator.hpp
#include <memory>
#include <Eigen/StdVector>
#include "is_fixed_size_vectorizable.hpp"
namespace foo {
template <typename T>
using allocator = std::conditional_t<is_fixed_size_vectorizable<T>::value,
Eigen::aligned_allocator<T>,
std::allocator<T>>;
} // end namespace foo
あとはこれを使ってSTLコンテナのエイリアスを作成します。
vector.hpp
#include <vector>
#include "allocator.hpp"
namespace foo {
template <typename T, typename Allocator = allocator<T>>
using vector = std::vector<T, Allocator>;
} // end namespace foo
std::vector<T>
の代わりにfoo::vector<T>
を使えば、T
がfixed-size vectorizableなEigenクラスの場合でも適切なアロケータが選択されます。