Re: [eigen] generic argument declaration taking a matrix, vector or expression

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


Am Montag, 16. Januar 2012, 13:43:49 schrieb Benoit Jacob:
> 2012/1/16 Martin Senst <martin.senst@xxxxxx>:
> > Am Donnerstag, 12. Januar 2012, 01:24:30 schrieb Benoit Jacob:
> >> 2012/1/11 Bernhard Zeisl <bzeisl@xxxxxxxxxxxxxxxx>:
> >> > Christoph, thanks a lot for your hint. That solved the problem.
> >> > 
> >> > I agree with you that with the new declaration we lost type safety.
> >> > Effectively A, b and x now can be of a different scalar type each.
> >> > While it's fine in our case that the function is templated over
> >> > different scalar types, it should be required that all arguments are
> >> > of the same type. Also it would be nice if that shows up in the
> >> > interface. As of now, I guess this is not possible?
> >> 
> >> As Christoph said, the only way to enforce that is by a static
> >> assertion, and that won't show up in the interface (if by interface
> >> you mean prototype). "Concepts" were supposed to make that possible
> >> but they got dropped from c++11, sadly.
> > 
> > You could use boost::enable_if to enforce that the scalar types of the
> > function parameters match. The following is C++11, but it should be
> > possible
> 
> > to make this work in C++03, too:

> Do these macros really work? I don't see how they can expand to a
> valid function prototype. Anyway, C++03 is what we need to target and
> there I don't think it's possible at all to implement enable_if in a
> way that doesn't require modifying function prototypes, as I meant
> above.


Hi Benoit,

yes, the macros work, I've tested them with g++ 4.5.3 using --std=c++0x. In 
C++03, you need to pass the enable_if-magic as a dummy function parameter, 
rather than in the template parameter list (see Section 3.1 in 
http://www.boost.org/doc/libs/1_48_0/libs/utility/enable_if.html for a 
discussion on enable_if in C++11), so yes, you need to modify the function 
prototype. I don't see the problem with this, however, because I understood 
that it is precisely Bernhard's intend to encode the requirement 
T1::Scalar==T2::Scalar in the function's interface. 
The following code is valid C++03, tested with g++ 4.5.3.


#include <Eigen/Dense>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>

#define EIGEN_ENABLE_IF_SAME_SCALAR(T1, T2) typename 
boost::enable_if<boost::is_same<typename T1::Scalar, typename T2::Scalar> 
>::type* dummy = 0

template <typename T1, typename T2>
void f(Eigen::MatrixBase<T1> t1, Eigen::MatrixBase<T2> t2, 
EIGEN_ENABLE_IF_SAME_SCALAR(T1, T2))
{
}

int main()
{
  Eigen::MatrixXd a, b;
  Eigen::MatrixXi c;
  f(a, b);
  //f(a, c); //Does not compile
}



Cheers,
Martin



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/