Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I move or assign one vector into another depending of their type using if constexpr?

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?

like image 970
T.L Avatar asked Jan 25 '26 08:01

T.L


1 Answers

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.

like image 99
Toby Speight Avatar answered Jan 26 '26 22:01

Toby Speight