Search code examples
c++templateslinear-algebrablitz++expression-templates

Why doesn't this Blitz++ code compile?


I'm a blitz++ newbie. So far, so good, but I'm a bit mystified why the commented out line in the code below fails to compile with

error: conversion from ‘blitz::_bz_tinyMatExpr<blitz::_bz_tinyMatrixMatrixProduct<double, double, 3, 3, 3, 3, 1, 3, 1> >’ to non-scalar type ‘const m33’ requested

I'm on Debian/Lenny (g++ 4.3.2, Blitz 0.9). Here's the code:

#include <blitz/blitz.h>
#include <blitz/array.h>
#include <blitz/matrix.h>
#include <blitz/matexpr.h>
#include <blitz/tinymat.h>
#include <blitz/tinymatexpr.h>
#include <blitz/tinyvec.h>
#include <blitz/tinyvec-et.h>
#include <blitz/vector.h>
#include <blitz/vector-et.h>

typedef blitz::TinyVector<double,3> v3;
typedef blitz::TinyMatrix<double,3,3> m33;

int main(int,char**)
{
  const m33 a;
  const m33 b;
  m33 c;c=blitz::product(a,b);  // Compiles OK
  //const m33 d=blitz::product(a,b);  // Fails to compile.
  return 0;
}

I do like to be const-ed to the hilt, so it'd be nice to know if there's a way of getting it to work (experience with Blitz++ so far suggests it might just be a matter of picking the right includes...).


Solution

  • I have had a look at the source code of Blitz++. As surprising as it may seem, there is no template constructor for TinyMatrix, but there is a template = operator. That means that you cannot do what you are trying to do. So I'd suggest forgetting about your matrix being const. Or find another way like creating a non-const matrix that you would pass as a const reference as the parameter of a function.

    Now, just for fun, the truth is you could copy template operator=() code and make a new template constructor inside blitz/tinymat.h out of it, but i wouldn't ! If you really want to, here's how :

    // Turn the following code...
    
    template<typename T_expr>
    TinyMatrix<T_numtype, N_rows, N_columns>&
    operator=(_bz_tinyMatExpr<T_expr> expr)
    {
        // USEFUL CODE
        return *this;
    }
    
    // ...into this :
    template<typename T_expr>
    TinyMatrix(_bz_tinyMatExpr<T_expr> expr)
    {
        // USEFUL CODE
    }
    

    and your code compiles (and probably works).