You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The reason is that, internally, Pack only deals with a non-const version of ScalarType, delegating const-correctness to the constness of *this only. While that can be helpful in keeping code complexity under control (see below), it can also cause a bit of puzzlement in new devs.
If T=const S, for some S, the return type is ok only because Pack<T,n> stores an array of std::remove_const<T>::type. Without this trick, the correct implementation of square would be
which is arguably a bit more complex. It would, however, avoid to accidentally change the entries of a Pack<const T,n> pack...
Note: we could also have, inside the Pack struct declaration, something like:
using non_const_type = Pack<typename std::remove_const<T>::type,n>;
which would turn the square signature into
template<typename T, int n>
typename Pack<T,n>::non_const_type square(const Pack<T,n>& p);
Not a huge improvement, but still smaller, and perhaps more verbose.
tl;dr Allowing a Pack<const double, 8> to be modified is counter-intuitive at best, and dangerous at worst. We should avoid bugs down the road due to this.
The text was updated successfully, but these errors were encountered:
Note: in order to allow initialization with a for loop (i.e., do the v[i]=... inside the ctor body), Pack<T,n> should still store an array of non-const scalars. What really matters is that it should have the op[] signature changed, like so:
The way the pack is implemented now, this code
compiles, and prints
The reason is that, internally,
Pack
only deals with a non-const version of ScalarType, delegating const-correctness to the constness of*this
only. While that can be helpful in keeping code complexity under control (see below), it can also cause a bit of puzzlement in new devs.The current behavior is handy in fcns like this:
If
T=const S
, for some S, the return type is ok only becausePack<T,n>
stores an array ofstd::remove_const<T>::type
. Without this trick, the correct implementation ofsquare
would bewhich is arguably a bit more complex. It would, however, avoid to accidentally change the entries of a
Pack<const T,n>
pack...Note: we could also have, inside the
Pack
struct declaration, something like:which would turn the
square
signature intoNot a huge improvement, but still smaller, and perhaps more verbose.
tl;dr Allowing a
Pack<const double, 8>
to be modified is counter-intuitive at best, and dangerous at worst. We should avoid bugs down the road due to this.The text was updated successfully, but these errors were encountered: