I wanted to move or assign a std::vector<Scalar> into a std::vector<float> depending on the type Scalar.
If Scalar is float then move, else copy.
I tried this code
#include <vector>
using Scalar = double;
int main()
{
std::vector<Scalar> x(10);
std::vector<float> y(10);
if constexpr(std::is_same<Scalar, float>::value)
y = std::move(x); // line 11 (does not compile)
else
y.assign(x.begin(), x.end());
return 0;
}
but I get
main.cpp:11:24: error: no match for ‘operator=’ (operand types are ‘std::vector<float>’ and ‘std::remove_reference<std::vector<double>&>::type’ {aka ‘std::vector<double>’})
11 | y = std::move(x);
| ^
I thought that since std::is_same<Scalar, float>::value is evaluated to false at compile-time, then the line below would not be compiled.
I compiled it using g++ -std=c++17 main.cpp -o exec.
How can I move/assign x into y depending on the Scalar type?
Because main() isn't a template, both sides of the if constexpr must be valid. To use if constexpr this way, it needs to be in a template.
Thankfully, a good template makes this logic more reusable:
#include <vector>
template<typename T, typename U>
void move_or_copy(std::vector<T>& dest, std::vector<U>&& src)
{
if constexpr(std::is_same_v<T,U>)
dest = std::move(src);
else
dest.assign(src.begin(), src.end());
}
using Scalar = double;
int main()
{
std::vector<Scalar> x(10);
std::vector<float> y(10);
move_or_copy(y, std::move(x));
}
We could make the template function better constrained (allow any collection as source), but this should at least provide the correct direction in which to depart.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With