[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