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