2017-12-01 3 views
2

Der folgende Code nicht kompilieren:nicht binden kann nicht konstante lvalue Referenz vom Typ 'int &' zu einem R-Wert vom Typ 'int'

#include <iostream> 

using namespace std; 

int add2(const int& x) 
{ 
    return x + 2; 
} 

template <typename T> 
T add2T(T&& x) { 
    return add2(std::forward<T>(x)); 
} 

int main(int argc, char** argv) { 
    int x = 0; 

    cout << "Add 2" << endl; 

    cout << add2(2) << endl; 
    cout << add2(x) << endl; 

    cout << "Add 2T" << endl; 

    cout << add2T(10) << endl; 
    cout << add2T(x) << endl; 

    return 0; 
} 

Mit dieser Nachricht:

main.cpp: In instantiation of 'T add2T(T&&) [with T = int&]': 
main.cpp:26:20: required from here 
main.cpp:12:16: error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int' 
    return add2(std::forward<T>(x)); 
      ~~~~^~~~~~~~~~~~~~~~~~~~ 

I‘ Ich bin mir nicht sicher, warum der Compiler versucht, die nicht konstante Lvalue-Referenz an einen Rvalue zu binden. Der Forward sollte sowieso in eine Lvalue-Referenz zerfallen, oder?

Antwort

3

Das Problem bezieht sich nicht auf Forward.

In dem Aufruf add2T(x) ist das abgeleitete Template-Argument Tint&. (Nur so kann T&& ein Lvalue-Referenztyp sein.) Daher ist der Rückgabetyp auch int&. Der Operand return (nämlich add2(std::forward<T>(x))) ist jedoch ein R-Wert, der nicht zum Initialisieren von int& verwendet werden kann. Daher die Fehlermeldung.

Wenn Sie den Rückgabetyp nicht zu einem Referenztyp verhindern möchten, können Sie std::decay_t anwenden:

template <typename T> 
std::decay_t<T> add2T(T&& x) 
+0

Right! Im Nachhinein ist es viel einfacher als ich dachte. Vielen Dank! –

Verwandte Themen