I've been trying to start using std::span<const T>
in places where I would have previously used const std::vector<T>&
. The only sticking point I have is illustrated in the following:
#include <iostream>
#include <vector>
#include <span>
#include <numeric>
double mean1(std::span<const double> vals) {
return std::accumulate(vals.begin(), vals.end(), 0.0) / vals.size();
}
double mean2(const std::vector<double>& vals) {
return std::accumulate(vals.begin(), vals.end(), 0.0) / vals.size();
}
int main() {
std::vector<double> foo = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
auto v = mean1(foo);
std::cout << v << "\n";
v = mean2( { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 } );
std::cout << v << "\n";
v = mean1({ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 } ); // << this is an error
std::cout << v << "\n";
}
I know that passing std:vector{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 }
would work but that is pretty verbose. initializer_list
is even more verbose. Just wondering if I am missing something obvious here.
The specific error from Visual Studio is
C2664 'double mean1(std::span<const double,18446744073709551615>)': cannot convert argument 1 from 'initializer list' to 'std::span<const double,18446744073709551615>'
I think, basically, std::span
doesn't have a constructor that takes an initializer list.
CodePudding user response:
you can use
mean1( {{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 }} );
which invoke the raw array constructor.
if you want to specify the type, I'd suggest
mean1( std::initializer_list{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 } )
which prevent the potential construction of another container. (which still construct a initializer_list
anyway)