我需要一系列初始化函数,使用可变数量的值。我正在使用它们来实现与Eigen库的收集操作。这是我现在使用每个向量长度的一个模板的方式:
template<typename T1, typename T2>
inline void gather (Array<T1,4,1> &to, const Array<T2,Dynamic,1> &from, const Array<int,4,1> &index)
{
to << from[index[0]], from[index[1]], from[index[2]], from[index[3]];
}
template<typename T1, typename T2>
inline void gather (Array<T1,6,1> &to, const Array<T2,Dynamic,1> &from, const Array<int,6,1> &index)
{
to << from[index[0]], from[index[1]], from[index[2]], from[index[3]], from[index[4]], from[index[5]];
}
有没有办法用一个参数化长度参数的模板(上面的代码段中的4和6)替换上面模板的更长列表?如果是这样,是否可以使用预C ++ 11语言规范(我使用的是Visual Studio 2010)?
我想保留逗号分隔值语法,因为我希望在某些情况下可能会产生编译时初始化(const from
和index
)。我可能在这个假设中错了。初始化列表可以包含1到16个值 - 无需担心空列表。
答案 0 :(得分:2)
基于重载operator,
运算符来概括这种语法是非常棘手的,结果看起来很尴尬(如果它有效)。我建议尝试其他选项(例如,转到MatrixBase::operator<<(DenseBase&)
运算符)。
如果你还想要它,你必须逐个解包标量:
template<typename T1, typename T2, class CI, int Current, int Height>
inline void gather (Array<T1,Height,1> &to, const Array<T2,Dynamic,1> &from, const Array<int,Height,1> &index, CI&& ci, std::integral_constant<int, Current>*)
{
gather(to, from, index, (ci,from[index[Current]]), (std::integral_constant<int, Current+1>*)0);
}
template<typename T1, typename T2, class CI, int Height>
inline void gather (Array<T1,Height,1> &to, const Array<T2,Dynamic,1> &from, const Array<int,Height,1> &index, CI&& ci, std::integral_constant<int, Height>*) {}
template<typename T1, typename T2, int Height>
inline void gather (Array<T1,Height,1> &to, const Array<T2,Dynamic,1> &from, const Array<int,Height,1> &index) {
gather(to, from, index, (to << index[from[0]]), (std::integral_constant<int, 1>*)0);
}
丑陋,可能存在问题(如果可能,您需要处理Dynamic
值,零高度,将CommaInitializers
传递给递归等可能会出现问题。)
另外,它具有线性模板实例化深度(在这种情况下,恕我直言,这是不可避免的)。
答案 1 :(得分:2)
在此设置中不要使用逗号初始化程序语法,这会很麻烦。在使用文字时,此语法用于可读性,而不是您的情况。
相反,我会建议像:
template<typename T1, typename T2, unsigned int SIZE, unsigned int INDEX>
struct gather {
gather(Array<T1,SIZE,1> &to,
const Array<T2,Dynamic,1> &from,
const Array<int,SIZE,1> &index)
{
to.col(INDEX) = from[index[INDEX]];
gather<T1,T2,SIZE,INDEX+1>(to,from, index);
}
};
template<typename T1, typename T2, unsigned int SIZE>
struct gather<T1,T2,SIZE,SIZE>{
gather(Array<T1,SIZE,1> &to,
const Array<T2,Dynamic,1> &from,
const Array<int,SIZE,1> &index)
{
}
};
很好地产生相同的效果,但是静态地(没有循环)。
我在这里使用一个结构,因为函数的部分模板特化限制,但由于内联,它应该归结为相同。