C++ valarray vs. vector
Valarrays (value arrays) are intended to bring some of the speed of Fortran to C++. You wouldn't make a valarray of pointers so the compiler can make assumptions about the code and optimise it better. (The main reason that Fortran is so fast is that there is no pointer type so there can be no pointer aliasing.)
Valarrays also have classes which allow you to slice them up in a reasonably easy way although that part of the standard could use a bit more work. Resizing them is destructive and they lack iterators they have iterators since C++11.
So, if it's numbers you are working with and convenience isn't all that important use valarrays. Otherwise, vectors are just a lot more convenient.
What is the difference between std::valarray and std::array
valarray
was already in C++03,array
is new in C++11valarray
is variable length,array
is not.valarray
is designed for numeric computations and provides plenty of operations including+
,-
,*
,cos
,sin
, etc...array
does not.valarray
has an interface to retrieve slices of the array (sub arrays),array
does not.
valarray vs. vector: Why was valarray introduced?
Separation of concern? A vector
and a valarray
solve different problems. Quoting from the standard, a vector
is a (§23.3.6.1 [vector.overview] p1
)
... sequence container that supports random access iterators. In addition, it supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage management is handled automatically, though hints can be given to improve efficiency.
while a valarray
is a (§26.6.2.1 [template.valarray.overview] p1
)
... one-dimensional smart array, with elements numbered sequentially from zero. It is a representation of the mathematical concept of an ordered set of values. The illusion of higher dimensionality may be produced by the familiar idiom of computed indices, together with the powerful subsetting capabilities provided by the generalized subscript operators.
As you can see, they serve different purposes. A vector
is a generalized dynamic array, while a valarray
represents a set of values. It's also not resizeable and only assignable.
Why are std::vector and std::valarray initializing constructors different?
Because they don't come from the same place: vector
comes from the STL library, and valarray
doesn't (I haven't been able to find out where it comes from, but there seem to be strong connections to Fortran).
Quoting Bjarne himself:
Most of the time, work on each of these components progressed in
isolation from work on the others. There was no overall design or
design philosophy.
[...]
Basically, the committee failed to contain “design by committee” so
whereas the STL reflects a clear philosophy and coherent style, most
of the other components suffered. Each represents its own style and
philosophy, and some (such asstring
) manage simultaneously to present several.
(From "Evolving a language in and for the real world: C++ 1991-2006".)
So I would say that the rationale is the traditional C++ one, "things are the way they are, and changing them for the sake of Standardization would break a lot of things, so let's leave well enough alone".
How to pass a vector or a valarray as an argument to a C++ template function
std::vector
has 2 template parameters. The second one is the allocator, which has a default value so you normally don't use it.
However, prior to c++17
template template parameters would only match if the number of template arguments where the same. In c++17 this was relaxed a bit and it's since allowed to match a template with more template parameters as long as the remaining ones have default arguments.
Regardless of this, I would propose a solution that uses the member type in both containers, value_type
.
#include <vector>
#include <algorithm>
#include <valarray>
template <class T>
auto GetPercentile(T& vData, double dPercentile)
{
using elType = typename T::value_type;
int iOffset = int(dPercentile * vData.size());
std::nth_element(begin(vData), begin(vData) + iOffset, end(vData));
return static_cast<elType>(vData[iOffset]);
}
int main() {
auto v = std::vector<int>{1,2,3,4,5};
GetPercentile(v, 2);
auto a = std::valarray<int>(5, 5);
GetPercentile(a, 2);
}
Assign a std::vector to a std::valarray
To create a valarray from a vector:
std::valarray<double> corpX(corps_tmp[i].data(), corps_tmp[i].size());
To write the data back into a vector:
corps_tmp[i].assign(std::begin(corpX), std::end(corpX));
Related Topics
C++ Array Assignment of Multiple Values
Spiral Rule and 'Declaration Follows Usage' for Parsing C and C++ Declarations
What Does the Operation C=A+++B Mean
What Does '&' Do in a C++ Declaration
What's Faster, Iterating an Stl Vector with Vector::Iterator or with At()
Call to Pure Virtual Function from Base Class Constructor
Passing a Variable as a Template Argument
How to Clone as Derived Object in C++
What Is the Meaning of "Operator Bool() Const"
Linking a Shared Library with Another Shared Lib in Linux
Check Traits for All Variadic Template Arguments
Using Cmake with Multiple Compilers for the Same Language
Is the Pass-By-Value-And-Then-Move Construct a Bad Idiom
Deleted Default Constructor. Objects Can Still Be Created... Sometimes