本征分配器导致模板化问题 Class
Eigen Allocator causing Trouble in Templated Class
我有这个class:
typedef vector<Eigen::Affine3d,Eigen::aligned_allocator<Eigen::Affine3d> > VoteList;
template <class T>
class KernelDensityEstimator {
public:
KernelDensityEstimator() {}
void setData(vector<T>& d) {
data = d;
}
void setKernel(double (*k)(T&, T&)) {
kernel = k;
}
double evaluate(T& p) {
double sum;
for (int i = 0; i < data.size(); i++) {
sum += (*kernel)(p, data[i]);
}
return sum/data.size();
}
private:
double (*kernel) (T&, T&);
vector<T> data;
};
我想暂时使用类型为 T = Eigen::Affine3d 的 with。但是,当我调用 setData()
时,它给我带来了麻烦,因为 Eigen 需要为标准容器指定 Eigen::aligend_allocator 以与 Eigen 一起使用。
因此,当我将 vector<Eigen::Affine3d,Eigen::aligned_allocator<Eigen::Affine3d> >
(又名 VoteList
)作为 setData()
的输入参数时,我的编译器会抱怨:
no known conversion for argument 1 from ‘VoteList {aka std::vector<Eigen::Transform<double, 3, 2>, Eigen::aligned_allocator<Eigen::Transform<double, 3, 2> > >}’ to ‘std::vector<Eigen::Transform<double, 3, 2>, std::allocator<Eigen::Transform<double, 3, 2> > >&’
哪一种说得通,但我认为分配器是对象类型的一部分。有没有办法解决这个问题并保持我的 KernelDensityEstimator
通用?
您基本上希望根据 class 模板参数类型 T
为您的成员 data
使用不同的类型。有几种方法可以做到这一点,这里是一个建议:
为您的 class 定义一个特殊的存储类型,您可以在其中保存数据(最好将其放在合适的命名空间中或在您的 class 中):
//normal storage type
template<typename T>
struct storage_type_impl
{
using type = std::vector<T>;
};
//storage type for Eigen::Transform types
template<typename ... Args>
struct storage_type_impl<Eigen::Transform<Args ...> >
{
using type = std::vector<Eigen::Transform<Args ...>
, Eigen::aligned_allocator<Eigen::Transform<Args ...> > >;
};
template<typename T>
using storage_type = typename storage_type_impl<T>::type;
现在您可以在 class 中使用它以及模板化的 setData
方法(这就足够了,因为编译器在无法执行数据时仍然会报错 copy/move):
template <class T>
struct KernelDensityEstimator
{
template<typename D>
auto setData(D&& d)
{
data = std::forward<D>(d); //calls move assignment if d is an rvalue
//otherwise a copy is performed
}
//...
private:
storage_type<T> data;
//...
};
代码未经测试,因为我目前没有可用的 Eigen,但我希望它仍然能够解释基本思想。
您可以为您计划使用的类型启用 Eigen 的 std::vector 特化,详见 there,例如:
#include<Eigen/StdVector>
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Affine3d)
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Matrix4d)
...
我有这个class:
typedef vector<Eigen::Affine3d,Eigen::aligned_allocator<Eigen::Affine3d> > VoteList;
template <class T>
class KernelDensityEstimator {
public:
KernelDensityEstimator() {}
void setData(vector<T>& d) {
data = d;
}
void setKernel(double (*k)(T&, T&)) {
kernel = k;
}
double evaluate(T& p) {
double sum;
for (int i = 0; i < data.size(); i++) {
sum += (*kernel)(p, data[i]);
}
return sum/data.size();
}
private:
double (*kernel) (T&, T&);
vector<T> data;
};
我想暂时使用类型为 T = Eigen::Affine3d 的 with。但是,当我调用 setData()
时,它给我带来了麻烦,因为 Eigen 需要为标准容器指定 Eigen::aligend_allocator 以与 Eigen 一起使用。
因此,当我将 vector<Eigen::Affine3d,Eigen::aligned_allocator<Eigen::Affine3d> >
(又名 VoteList
)作为 setData()
的输入参数时,我的编译器会抱怨:
no known conversion for argument 1 from ‘VoteList {aka std::vector<Eigen::Transform<double, 3, 2>, Eigen::aligned_allocator<Eigen::Transform<double, 3, 2> > >}’ to ‘std::vector<Eigen::Transform<double, 3, 2>, std::allocator<Eigen::Transform<double, 3, 2> > >&’
哪一种说得通,但我认为分配器是对象类型的一部分。有没有办法解决这个问题并保持我的 KernelDensityEstimator
通用?
您基本上希望根据 class 模板参数类型 T
为您的成员 data
使用不同的类型。有几种方法可以做到这一点,这里是一个建议:
为您的 class 定义一个特殊的存储类型,您可以在其中保存数据(最好将其放在合适的命名空间中或在您的 class 中):
//normal storage type template<typename T> struct storage_type_impl { using type = std::vector<T>; }; //storage type for Eigen::Transform types template<typename ... Args> struct storage_type_impl<Eigen::Transform<Args ...> > { using type = std::vector<Eigen::Transform<Args ...> , Eigen::aligned_allocator<Eigen::Transform<Args ...> > >; }; template<typename T> using storage_type = typename storage_type_impl<T>::type;
现在您可以在 class 中使用它以及模板化的
setData
方法(这就足够了,因为编译器在无法执行数据时仍然会报错 copy/move):template <class T> struct KernelDensityEstimator { template<typename D> auto setData(D&& d) { data = std::forward<D>(d); //calls move assignment if d is an rvalue //otherwise a copy is performed } //... private: storage_type<T> data; //... };
代码未经测试,因为我目前没有可用的 Eigen,但我希望它仍然能够解释基本思想。
您可以为您计划使用的类型启用 Eigen 的 std::vector 特化,详见 there,例如:
#include<Eigen/StdVector>
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Affine3d)
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Eigen::Matrix4d)
...