Registered Member
|
Hi. I've got the following testcase:
It produces the following output:
That is clearly the wrong answer (I'm expecting the vector (0.5, 0.5, 0.5)^T). I can reproduce this problem with GCC 4.7.0 (Fedora 17) with Eigen 3.1.1, and with GCC 4.6.3 (Ubuntu 12.04) with Eigen 3.0.5. Making foo a non-template, replacing all T's for Eigen::Vector3, results in “error: no match for ‘operator*’ in ‘5.0e-1 * f’”. Since I have been unable to reproduce this problem without Eigen, I assume this must be something to do with Eigen or with my using Eigen. So – does anyone have an idea what might be wrong here? Thanks. |
Registered Member
|
If you replace the last line with "std::cout << (0.5 * Eigen::Vector3d(f)) << '\n';" the problem goes away. The is something strange occurring in your implicit cast (implicit casts should be avoided IMHO).
|
Registered Member
|
Indeed, with an explicit conversion it works. There can't be much wrong going on in the implicit conversion function, as it's just a simple return of a copy of a vector. The problem must be in the interaction of this implicit conversion with the rest of Eigen. I'm still wondering what kind of interaction that is.
|
Moderator
|
To be honest I'm surprised this does compile. It seems the cast operator is implicitly called only for a scalar multiple product, not for other operators involving a foo<> and a Vector3d. I also cannot reproduce the error with clang. Returning a const reference also fixes the issue.
|
Registered Member
|
I agree, this code probably shouldn't compile. I dug into it, and didn't really find a reason why it compiles at all. I tried explicitely calling op *, using Eigen::operator * (0.5, f), but that failed to compile. Yet, tracing through a debugger, I can clearly see Eigen::operator * (Scalar, Eigen::MatrixBase<Eigen::Matrix<…> >::StorageBaseType const&) called.
Unfortunately, I haven't been able to isolate those parts of Eigen that make this compile either. It's strange you haven't reproduced the problem with Clang, though. I have been able to reproduce it with Clang 3.0 and Microsoft's Visual C++ 2010. Also, from my debugging, I learned that what happens is roughly the following: operator T () gets called, and the vector gets copied. Then Eigen::op * (Scalar, Matrix) is called, which in turn calls Eigen::Matrix::operator * (Scalar). Then an object of type CwiseUnaryOp gets created which is supposed to contain the vector – however, the Matrix instance inside CwiseUnaryOp (m_xpr member) appears to be uninitialized – it also appears to have a different address from that copy that was created by calling operator T (). Then the product of 0.5 with this uninitialized matrix is computed and printed. |
Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]