Re: [eigen] TriangularViewType& operator/=(const typename internal::traits<MatrixType>::Scalar& other) |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
Dear Gael,
Am 06.09.2016 um 16:35 schrieb Gael Guennebaud:
[...]
nope, that does not work for real, for instance the following lines will fail because typename NumTraits<T>::Real==T and you will have the same specialization twice.
you are completely right.
I did the test for the real case at an earlier step.
Just for anyone interested in some C++ fun, a comment from my 'digging into Eigen' project.
When adding Eigen::JacobiSVD to my example, compilation fails again, since we now also need
a conversion from Eigen::Index, which turns out to be long, to MyType.
After adding the corresponding constructor,
MyType( const long z) : za(z), zb(0) {}; //needed for eigen
compilation fails again for reasons which are beyond my C++ knowledge.
Suddenly the compiler also request for a constructor with a double argument,
even MyType r(2.0); fails now.
For some reasons, after adding the long-constructor, double doesn't get promoted to complex any more.
This behaviour occurs with g++ and clang.
Of course, that's easy to fix, by adding the corresponding constructor. In doing so, I realized,
that one doesn't need the weird enable_if based constructors. One can simply use
template< typename Q = T> MyType( const MyType < typename Q::value_type>& a ) : za(a.z1() ), zb(a.z2()) {};
template< typename Q = T> MyType( const typename Q::value_type a ) : za(a ) , zb(0) {};
which doesn't get instantiated for double, as it doesn't possess a value_type, while complex<T> has.
Since I never really understood the application of enable_if for constructors, I think this construction
is much simpler to understand.
Best regards,
Peter
#include <iostream>
#include <cmath>
#include <complex>
// g++ -std=c++11 -g Test_constructors.C -o Test 2>&1 | tee Err.txt | more
template<typename T>
class MyType
{
public:
typedef T value_type;
MyType( const T a, const T b ) : za(a), zb(b) {};
MyType( const MyType& a) : za(a.za), zb(a.zb) {};
MyType( const T& z) : za(z), zb(0) {};
MyType( const int z) : za(z), zb(0) {}; //needed for eigen
MyType() {};
const T& z1() const { return za; };
T& z1() { return za; };
const T& z2() const { return zb; };
T& z2() { return zb; };
template< typename Q = T>
MyType( const MyType < typename Q::value_type>& a ) : za(a.z1() ), zb(a.z2()) {};
//--------------------------------------
// fun part in the next 2 constructors
//--------------------------------------
//MyType( const long z) : za(z), zb(0) {}; ///< if this one is added, the next one is also needed
//template< typename Q = T> MyType( const typename Q::value_type a ) : za(a ), zb(0) {};
private:
T za, zb;
};
typedef double TpFloatBase;
typedef std::complex<TpFloatBase> TpComplex;
typedef MyType < TpFloatBase > TpRFloat;
typedef MyType < TpComplex > TpFloat;
int main( )
{
TpRFloat r(1);
TpFloat q(2);
TpFloat z(2.0);
std::cout << z.z1() << ' ' << z.z2() << std::endl;
return 0;
}