0

I was reading some documentation and saw this:

template<class Ret, class... Args>
struct is_function<Ret(Args...) &&> : std::true_type {};

Quoted from: http://en.cppreference.com/w/cpp/types/is_function

How can you have a rvalue reference to a function?

From what I understand, functions don't have storage lifetimes. Could someone explain this? I understand references and pointers but how can you "move" a function?

I wrote this code and it compiles and runs as it should:

#include <iostream>
using namespace std;

int foo(int num) {
    return num + 1;
}

int main() {

    int (*bar1)(int) = &foo;
    cout << bar1(1) << endl;

    int (&bar2)(int) = foo;
    cout << bar2(2) << endl;

    auto bar3 = std::move(bar2); // ????
    cout << bar3(3) << endl;
    cout << bar2(2) << endl;

    int (&&bar4)(int) = foo; // ????
    cout << bar4(4) << endl;

}

Lets just say if you could store functions as bytecode/opcodes in memory, and 'move' that around. Wouldn't the CPU prevent it from running?

EDIT: @NicolBolas corrected my misunderstanding, but here is an answer for my other 'question': rvalue reference to function

Aryan
  • 608
  • 6
  • 15
  • 2
    Rvalue references don't mean "move". – Nicol Bolas Jan 11 '18 at 00:35
  • 5
    [Relevant](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0172r0.html) – chris Jan 11 '18 at 00:35
  • @NicolBolas I meant it as to apply move semantics. Instead of copying the machine instructions, it would 'move' it. – Aryan Jan 11 '18 at 00:38
  • 4
    You *can* have an rvalue reference to a function, but `Ret(Args...) &&` isn't it. It would be spelled `Ret (&&)(Args...)`. – Brian Bi Jan 11 '18 at 00:40
  • You can neither 'copy' nor 'move' machine instructions. None of this have anything to do with what's going on in your code. You are simply "moving" a function pointer. Moving a function pointer just copies it (same as for all fundamental types). – AnT stands with Russia Jan 11 '18 at 01:14

1 Answers1

4

How can you have a rvalue reference to a function?

That's not what that means.

The && at the end of Ret(Args...) && refers to the ability for a member function to have an rvalue this. So that specialization works for a function type that has Ret as the return value, Args as its arguments, and uses an rvalue this.

So it's not an "rvalue reference to a function". It's a function that takes an rvalue this.

Community
  • 1
  • 1
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • This doesn't look like the full story to me - a function doesn't take `this` at all, wouldn't it have to be a pointer-to-method declared as `Ret(Class::*)(Args...) &&`? – Eric Oct 06 '19 at 10:27
  • 1
    Ah, I see what I'm missing - `Ret (Class::*)(Args...) &&` can also be written `using F = Ret(Args...) &&;` `F Class::*`. – Eric Oct 06 '19 at 10:34