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;
}


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