Indiana Unversity logo[ConceptGCC]

ConceptGCC :

Re: Constrained concept maps

From: Doug Gregor (dgregor_at_[hidden])
Date: 2006-07-21 16:11:24


On Jul 18, 2006, at 2:49 PM, Bonderer Rolf wrote:

> Dear all,
>
> I intend to write concept maps for std::Multiplicable with ublas
> Matrices and Vectors. As you see below, I just use a concept map to
> declare that a certain type is a ublas Vector (Should I rather use
> SameType constraints etc.?!).

I don't think you'll need to use SameType constraints to do this, but...

> Do you have an idea why the following doesn't compile:
>
> #include <concepts>
> #include <boost/numeric/ublas/matrix.hpp>
> #include <boost/numeric/ublas/symmetric.hpp>
> #include <boost/numeric/ublas/vector.hpp>
>
> namespace ublas = boost::numeric::ublas;
>
> concept UblasMatrix<typename Matrix>
> { typename value_type = Matrix::value_type; };
> concept_map UblasMatrix<ublas::matrix<double> > {};
> // More maps of the form "concept_map
> UblasMatrix<ublas::symmetric_matrix<double> > {};" will be added,
> once this sample compiles
>
> concept UblasVector<typename Vector>
> { typename value_type = Vector::value_type; };
> concept_map UblasVector<ublas::vector<double> > {};
>
> namespace std {
>
> template<UblasMatrix Matrix, UblasVector Vector>
> concept_map std::Multiplicable<Matrix, Vector>
> {
> typedef typename
> ublas::matrix_vector_binary1_traits<Matrix::value_type, Matrix,
> Vector::value_type, Vector>::result_type result_type;
>
> inline result_type operator*(const Matrix& m, const Vector& v)
> {
> return ublas::prod(m,v);
> }
> }
>
> } //namespace std
>
> int main() {}

The error that pops out is something about promotion_traits... the
problem is that the return type of the matrix-vector produce is
computed with a metafunction, but that metafunction can't be
evaluated in a constrained template. It's a sticky situation, because
in general, traits really don't work well in constrained templates.
One approach you can use is to turn off type checking for the
concept_map, by marking the 'Matrix' template parameter with a '!',
e.g.,

   template<UblasMatrix! Matrix, UblasVector Vector>
   concept_map std::Multiplicable<Matrix, Vector>
   {
     typedef typename ublas::matrix_vector_binary1_traits<
               typename UblasMatrix<Matrix>::value_type, Matrix,
               typename UblasVector<Vector>::value_type,
Vector>::result_type
       result_type;

     inline result_type operator*(const Matrix& m, const Vector& v)
       {
         return ublas::prod(m,v);
       }
   }

That delays type-checking of operator* until instantiation time, so
the traits don't cause a problem.

(For reference, the latest Concepts proposal uses the "late_check"
keyword for this same kind of behavior, but ConceptGCC is lagging way
behind in implementing support for it.)

        Doug