Disclaimer: Grok generated document.
std::valarray is a C++ standard library container introduced in C++98 specifically for high-performance numerical computations on arrays of numeric types (like float, double, int, etc.). It was designed with the intention of allowing aggressive optimizations for mathematical operations, especially on entire arrays at once.
-
Element-wise mathematical operations with a clean syntax
std::valarray<double> a = {1, 2, 3, 4}; std::valarray<double> b = {5, 6, 7, 8}; auto c = a + b; // {6, 8, 10, 12} auto d = a * b; // {5, 12, 21, 32} auto e = sin(a) + cos(b); // applies sin/cos element-wise
-
Built-in support for mathematical functions (applied element-wise):
abs(),sqrt(),exp(),log(),sin(),cos(),tan(),acos(),asin(),atan(),sinh(),cosh(),tanh(),pow(), etc.
-
Slicing and indirect array access (advanced indexing)
std::valarray<double> v(12); std::slice s(0, 4, 3); // start=0, length=4, stride=3 v[s] = 99.0; // v[0], v[3], v[6], v[9] = 99.0 auto subset = v[std::gslice(...)]; // multi-dimensional-like slicing
-
Operations with scalars
auto x = a * 2.0 + 5.0; // every element multiplied by 2 and add 5
In the 1990s, people wanted something like MATLAB/NumPy in C++:
- Vectorized operations without explicit loops
- Potential for compiler optimizations (expression templates, loop fusion, SIMD)
- Clean mathematical syntax
Despite good intentions, std::valarray has major drawbacks and is widely considered a failed experiment:
| Issue | Explanation |
|---|---|
| Poor performance in practice | Most compilers do not apply the expected aggressive optimizations. Often slower than hand-written loops or std::vector with SIMD. |
| Expression templates missing | The original design assumed expression templates (like in Blitz++ or Eigen), but the standard version uses temporary objects → many copies. |
| Awkward, non-intuitive API | Slicing (std::slice, std::gslice, std::mask_array, std::indirect_array) is complex and hard to use correctly. |
| No dynamic allocation control | Always copies on operations unless compiler optimizes heavily (which it usually doesn’t). |
| No iterator support pre-C++11 | Made it incompatible with STL algorithms. |
| Very little real-world adoption | Almost no major numerical library (Eigen, Armadillo, Blaze, etc.) uses or recommends it. |
| Library | Advantages over std::valarray |
|---|---|
| Eigen | Extremely fast, expression templates, lazy evaluation, excellent SIMD, MATLAB-like syntax |
| blaze-lib | Modern C++ design, hybrid CPU/GPU, great performance |
| Armadillo | MATLAB-like syntax, integrates with LAPACK/BLAS |
| xtensor | NumPy-like API, multi-dimensional, lazy evaluation |
| std::mdspan (C++23) + std::simd (upcoming) | Future standard solution for multi-dimensional arrays and explicit SIMD |
Simple std::vector + loops + SIMD intrinsics/OpenMP |
Often faster and much clearer |
Use std::valarray only if:
- You are maintaining very old numerical code that already uses it.
- You are doing educational experiments with the original C++98 numerical array design.
Do NOT use std::valarray for new code if performance or clarity matters.
For any serious numerical work in modern C++, use Eigen, blaze, xtensor, or wait for the emerging standard solutions based on std::mdspan and std::simd.
In short: std::valarray is an interesting historical artifact with a great idea that never quite worked out in practice.
