Целочисленные параметры шаблона и вызовы подфункций
В этом коротком фрагменте я хочу создать Eigen::Tensor (в неподдерживаемом модуле) с размерами aribtrary.
template
<typename T>
Tensor<T, 2> convertNPToEigen2D(np::ndarray const & arr)
{
//Some checking...
T* raw_arr_data = reinterpret_cast<T*>(arr.get_data());
TensorMap<Tensor<T, 2>> arr_eigen(raw_arr_data,
arr.shape(0), arr.shape(1));
//...
return arr_eigen;
}
Конечно, вы можете видеть, что без шаблонов с переменным числом я должен дублировать эту функцию для каждого возможного числа измерений. Это похоже на довольно простые примеры, где вариационные шаблоны могут избежать большого количества дублирования кода:
template
<typename T, uint64_t dims>
Tensor<T, dims> convertNPToEigenND(np::ndarray const & arr)
{
//Some checking...
T* raw_arr_data = reinterpret_cast<T*>(arr.get_data());
TensorMap<Tensor<T, dims>> arr_eigen(raw_arr_data,
/*arr.shape(0), ..., arr.shape(dims-1)*/);
//...
return arr_eigen;
}
У меня есть несколько проблем с переводом этого кода в шаблон переменной, поскольку у меня нет пакета аргументов. Я предполагаю, что было бы также возможно позволить звонящему делать работу, т.е.
convertNPToEigenND<float, arr.shape(0), arr.shape(1), arr.shape(2)>(arr)
но я бы предпочел вышеуказанное решение, если это возможно. Я думал, что будет легко разобраться в этой проблеме, но большинство вопросов, которые я нашел, касаются существующего пакета аргументов, а не его создания.
Заранее спасибо!
редактировать
Спасибо, решение сработало отлично. Мне нужно просто еще одно простое расширение:
array<int, sizeof...(Is)> shuffle_tens = { Is... };
reverse(shuffle_tens.begin(), shuffle_tens.end());
Я попытался использовать простое решение с этого сайта, но оно говорит мне "не может конвертировать из 'ints<5,4,3,2,1,0>' в 'int'".
Еще раз спасибо Jarod42,
array<int, sizeof...(Is)> shuffle_tens = { (sizeof...(Is) - Is - 1)... };
работает для меня.
1 ответ
Вы могли бы использовать std::index_sequence
:
template <typename T, size_t ... Is>
Tensor<T, sizeof...(Is)> convertNPToEigenNDHelper(np::ndarray const & arr,
std::index_sequence<Is...>)
{
//Some checking...
T* raw_arr_data = reinterpret_cast<T*>(arr.get_data());
TensorMap<Tensor<T, sizeof...(Is)>> arr_eigen(raw_arr_data, arr.shape(Is)...);
//...
return arr_eigen;
}
template
<typename T, uint64_t dims>
Tensor<T, dims> convertNPToEigenND(np::ndarray const & arr)
{
return convertNPToEigenNDHelper<T>(arr, std::make_index_sequence<dims>());
}
std::index_sequence
/std::make_index_sequence
являются C++14, но могут быть реализованы в C++11.