Consider the following program:
#include <iostream> #include <ostream> #include <vector> #include <valarray> #include <algorithm> #include <iterator> template<typename Array> void print(const Array& a) { using namespace std; typedef typename Array::value_type T; copy(&a[0], &a[0] + a.size(), ostream_iterator<T>(std::cout, " ")); } template<typename T, unsigned N> unsigned size(T(&)[N]) { return N; } int main() { double array[] = { 0.89, 9.3, 7, 6.23 }; std::vector<double> v(array, array + size(array)); std::valarray<double> w(array, size(array)); print(v); // #1 std::cout << std::endl; print(w); // #2 std::cout << std::endl; }
While the call numbered #1 succeeds, the call numbered #2 fails because the const version of the member function valarray<T>::operator[](size_t) returns a value instead of a const-reference. That seems to be so for no apparent reason, no benefit. Not only does that defeats users' expectation but it also does hinder existing software (written either in C or Fortran) integration within programs written in C++. There is no reason why subscripting an expression of type valarray<T> that is const-qualified should not return a const T&.