Hi
(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.
Markus
--
PGP key on www.esat.kuleuven.be/~mmoll/public_key.pgp
Fingerprint is
90C4 B47D 1A00 5AC1 9147 3197 EDA7 1E0E 99E4 9EDB