我有一个3D multi_array,我想使用运行时指定的维度制作2D切片。我知道退化维度的索引和我想要在该简并维度中提取的切片的索引。目前丑陋的解决方案看起来像这样:
if (0 == degenerate_dimension)
{
Slice slice = input_array[boost::indices[slice_index][range()][range()]];
}
else if (1 == degenerate_dimension)
{
Slice slice = input_array[boost::indices[range()][slice_index][range()]];
}
else if (2 == degenerate_dimension)
{
Slice slice = input_array[boost::indices[range()][range()][slice_index]];
}
有没有更漂亮的方法来构造index_gen对象? 这样的事情:
var slicer;
for(int i = 0; i < 3; ++i) {
if (degenerate_dimension == i)
slicer = boost::indices[slice_index];
else
slicer = boost::indices[range()];
}
Slice slice = input_array[slicer];
似乎每次对boost :: indices :: operator []的后续调用都会返回一个不同的类型,具体取决于维度(即先前调用的数量),因此无法使用单个变量,可以保存临时index_gen对象
答案 0 :(得分:3)
请试试这个。 Сode有一个缺点 - 它指的是在boost :: detail :: multi_array命名空间中声明的ranges_数组变量。
#include <boost/multi_array.hpp>
typedef boost::multi_array<double, 3> array_type;
typedef boost::multi_array_types::index_gen::gen_type<2,3>::type index_gen_type;
typedef boost::multi_array_types::index_range range;
index_gen_type
func(int degenerate_dimension, int slice_index)
{
index_gen_type slicer;
int i;
for(int i = 0; i < 3; ++i) {
if (degenerate_dimension == i)
slicer.ranges_[i] = range(slice_index);
else
slicer.ranges_[i] = range();
}
return slicer;
}
int main(int argc, char **argv)
{
array_type myarray(boost::extents[3][3][3]);
array_type::array_view<2>::type myview = myarray[ func(2, 1) ];
return 0;
}
答案 1 :(得分:-2)
您要做的是将变量从运行时间移动到编译时。这只能通过一系列if else
语句或switch
语句来完成。
简化示例
// print a compile time int
template< int I >
void printer( void )
{
std::cout << I << '\n';
}
// print a run time int
void printer( int i )
{
// translate a runtime int to a compile time int
switch( i )
{
case 1: printer<1>(); break;
case 2: printer<2>(); break;
case 3: printer<3>(); break;
case 4: printer<4>(); break;
default: throw std::logic_error( "not implemented" );
}
}
// compile time ints
enum{ enum_i = 2 };
const int const_i = 3;
constexpr i constexper_i( void ) { return 4; }
// run time ints
extern int func_i( void ); // { return 5; }
extern int global_i; // = 6
int main()
{
int local_i = 7;
const int local_const_i = 8;
printer<enum_i>();
printer<const_i>();
printer<constexpr_i()>();
//printer<func_i()>();
//printer<global_i>();
//printer<local_i>();
printer<local_const_i>();
printer( enum_i );
printer( const_i );
printer( constexpr_i() );
printer( func_i() ); // throws an exception
printer( global_i ); // throws an exception
printer( local_i ); // throws an exception
printer( local_const_i ); // throws an exception
}