I understand that doing something like the following:
auto&& x = Matrix1() + Matrix2() + Matrix3();
std::cout << x(2,3) << std::endl;
Will cause a silent runtime error if the matrix operations use expression templates (such as boost::ublas
).
Is there any way of designing expression templates to prevent the compiler from compiling such code that may result in the use of expired temporaries at runtime?
(I've attempted unsuccessfully to work around this issue, the attempt is here)
As I understnad, root of your problem is that expression template temporary may have references/pointers to some another temporaries. And by using auto&& we only extend life of expression template temporary itself, but not lifetime of temporaries it has references to. Is it right?
For instance, is this your case?
If yes then one of possible solutions, is to make special kind of expression template temporaries which hold resources moved from temporaries.
For instance, check this approach (you may define BUG_CASE macro, to get again bug case).
Your operator/function overloads may return different types, depending on T&&/const T& arguments:
So, when your expression template temporary do not have resources moved from temporaries - it's size will be not affected.
No. This was actually recognized before C++11's final standardization, but I don't know if it was ever brought to the committee's notice. Not that a fix would have been easy. I suppose the simplest thing would be a flag on types that would simply error if
auto
tries to deduce it, but even that would be complex becausedecltype
can also deduce it, as well as template argument deduction. And all three of these are defined in the same way, but you probably don't want the latter to fail.Just document your library appropriately and hope that nobody tries to capture them that way.