C++11 recursive function using "&&" rvalue reference leads to compilation error

Viewed 64

I tried to write some algorithm using recursive function and met this:

#include<vector>
using namespace std;
void f(vector<int>&& v) {
    if (!v.empty()) {
        // do some work
        v.pop_back();
        f(v); // compilation error!!!
    }
    return;
}

int main() {
    f(vector<int>{1, 2, 3});//ok
    return 0;
}

It doesn't compile, error message:

x86-64 clang 14.0.0
-std=c++11
<source>:7:9: error: no matching function for call to 'f'
        f(v);
        ^
<source>:3:6: note: candidate function not viable: expects an rvalue for 1st argument
void f(vector<int>&& v) {
     ^
1 error generated.

The reason I used "&&" is that I hope it could receive some r-value input parameter and use it as reference(not copy). I also tried to change f into generic function:

template<typename T>
void f(vector<T>&& v) {

Still fails.

How to fix this?

1 Answers

I have replaced

template<typename T>
void f(vector<T>&& v) {

By

template<typename T> void f(T&& v)

In your case it's a rvalue reference and in the second case it's a forwarding-reference (sometime call universal reference)

Demo : https://wandbox.org/permlink/ZbvOoB0kcyYPVzlq

In the line

    f(v); // compilation error!!!

v is an lvalue reference, so you have 2 choices :

  1. Transform it into a rvalue reference via an std::move like suggested in comment
  2. Allow f to works with lvalue reference. This can be done with forwarding-reference like in my example or by adding an overload for lvalue reference : void f(vector<int>& v). If you look at https://cppinsights.io/s/2f683e1c you will see that both code will do the same.
Related