Content |
Const-Correctness
In FLENS matrix/vector views act and behave like references in C++ just for matrix/vector parts instead of scalar values:
Pure C++ Types |
Analogous Role of FLENS Types |
int |
DenseVector<Array<double> > |
int & |
DenseVector<ArrayView<double> > |
const int & |
const DenseVector<ConstArrayView<double> > |
Views in FLENS
The beauty of this FLENS approach is that you can write functions that take any kind of DenseVector:
void
dummy(const DenseVector<VX> &x);
or
void
dummy(DenseVector<VX> &x);
Using traits you also can implement functions that accept non-const rvalues
typename RestrictTo<IsDenseVector<VX>::Type,
void>::Type
dummy(VX &&x); a
the latter is necessary in an expression like
where the view is a temporary object.
Design Flaw in MTL4
If you want to provide views you really need different types for const and non-const views. Till the moment of this writing (2012/09/01) the MTL4 guys think there was a 'simpler way'. As a consequence the const attribute is only decoration. In a large application this can lead to bugs that are hard to find. But even worse, even the compiler can not trace that you are violating const correctness. So for optimizations the compiler might rely on the const attribute. That means bugs will depend on your level of optimization (i.e. in debug mode you application works find but crashes in non-debug mode).
MTL4 Example
#include <boost/numeric/mtl/mtl.hpp>
using namespace mtl; using mtl::iall;
//
// we feed the beast with a const reference
//
void
beast(const dense2D<double> &A)
{
dense2D<double> B = sub_matrix(A, 0, 5, 0, 5);
B[1][1] = 666;
}
int main(int, char**)
{
using namespace mtl; using mtl::iall;
const int m = 5, n = 5;
dense2D<double> A(n, n);
for (int i=0; i<m; ++i) {
for (int j=0; j<n; ++j) {
A[i][j] = i+j;
}
}
std::cout << "before: A is\n" << A << "\n";
//
// calling the beast
//
beast(A);
std::cout << "after: A is\n" << A << "\n";
return 0;
}
Compile and Run
$shell> cd flens/examples $shell> clang++ -I/opt/local/include/ -I$HOME/MTL/usr/include -o design-flaws-mtl4 design-flaws-mtl4.cc $shell> ./design-flaws-mtl4 before: A is [0 1 2 3 4] [1 2 3 4 5] [2 3 4 5 6] [3 4 5 6 7] [4 5 6 7 8] after: A is [ 0 1 2 3 4] [ 1 666 3 4 5] [ 2 3 4 5 6] [ 3 4 5 6 7] [ 4 5 6 7 8]