Re: [eigen] Can we prevent that this compiles?

[ Thread Index | Date Index | More Archives ]


(I hope this doesn't arrive too often. I first sent it from an account that I 
haven't subscribed to the list with, then through an unconfigured mail system, 
so this is the third try ;-) )

On Wednesday 30 September 2009 13:38:41 Hauke Heibel wrote:
> MatrixXd m = MatrixXd::Random(2,10);
> Replicate<MatrixXd,2,1> first_row_twice(m.row(0));
> Whereas it should be:
> MatrixXd m = MatrixXd::Random(2,10);
> Replicate<MatrixXd::RowXpr,2,1> first_row_twice(m.row(0));
> My question is whether somebody has an idea of preventing the first version
> to compile? I fear that it will not be possible to prevent the compilation
> which is unfortunate since this error is quite subtle...

Off the top of my head: C++ allows implicit conversions of the form built-in -
user -> built-in. So the problem is that there is a user conversion from 
MatrixXd::RowXpr to MatrixXd. The classical solution is to force an extra 
user-defined conversion:

template<typename T>
struct ConstRef
	const T& t;
	ConstRef(const T& t) : t(t) {}

template<typename T, [...] >
class Replicate
	Replicate(const ConstRef<T>& cref);

Now unless someone passes an ConstRef (which then really is a conscious 
choice), there is a necessary user-defined implicit conversion const T& -> 
ConstRef<T>, so another (user-defined) conversion from say U to T is not 
considered any longer. Just confirmed that with a small sample program.


PGP key on
Fingerprint is 
90C4 B47D 1A00 5AC1 9147  3197 EDA7 1E0E 99E4 9EDB

Mail converted by MHonArc 2.6.19+