Reputation: 15560
I have a 3D array of double
s. I want to write simple & generic function to print 2D slices of it.
Code:
#include <cstdio>
#include <boost/multi_array.hpp>
template<class M> // any model of MultiArray concept
void printFloatMatrix(typename M::template array_view<2u>::type matrix) {
using std::printf;
for(auto& row : matrix) {
for(auto& elem : row) {
printf("%5.3f ", elem);
}
printf("\n");
}
}
int main() {
typedef boost::multi_array<double,3> data_t;
data_t test_matrix{data_t::extent_gen()[10][10][2]};
// ...
using boost::indices;
using boost::multi_array_types::index_range;
printFloatMatrix(test_matrix[ indices[index_range()] [index_range()] [0] ]);
}
With GCC this produces the error message:
test.cpp: In function ‘int main()’:
test.cpp:24:79: error: no matching function for call to ‘printFloatMatrix(boost::multi_array_ref<double, 3u>::array_view<2u>::type)’
test.cpp:24:79: note: candidate is:
test.cpp:5:6: note: template<class M> void printFloatMatrix(typename M::array_view<2u>::type)
Why the error?
Why doesn't M
is inferred to be boost::multi_array_ref<double, 3u>
?
How do I write the prototype that'd work?
Upvotes: 4
Views: 641
Reputation: 16242
Sure, you have to constrain your arguments:
template<class M,
std::enable_if_t<M::dimensionality == 2 and std::is_same_v<typename M::element, double>, int> =0
>
void printFloatMatrix(const M& matrix)
Upvotes: 1
Reputation: 15560
I'm not able to spell the exact reason why C++ type inference fails here, but changing the function prototype to template<class M> void printFloatMatrix(const M& matrix)
worked.
The prototype is uselessly wide now, though. With high chance it will bite me in the future. This situation will hopefully be fixed with the advent of concepts, or can alternatively be worked-around with static asserts.
Thanks to ##c++
at Freenode.
Upvotes: 1