web-dev-qa-db-ja.com

タイプの非定数参照の無効な初期化

次のコードでは、printAge関数の引数として一時オブジェクトを渡すことができません。

struct Person {
  int age;
  Person(int _age): age(_age) {}
};

void printAge(Person &person) {
   cout << "Age: " << person.age << endl;
}

int main () {
  Person p(50);
  printAge(Person(50));  // fails!
  printAge(p);
  return 0;
}

私が得るエラーは:

error: invalid initialization of non-const reference of type ‘Person&’ from an rvalue of type ‘Person’

これは、rValueを期待する関数にlValueを渡すことと関係があることを理解しています... std :: moveなどを使用してlValueをrValueに変換する方法はありますか?定数パラメーターを使用してみましたが、うまくいかないようです。

16
jeffreyveon

印刷関数にconst&。あなたの議論を変更しないので、これも論理的に正しいです。

void printAge(const Person &person) {
   cout << "Age: " << person.age << endl;
}

実際の問題は逆です。左辺値を期待する関数にtemporary(rvalue)を渡しています。

16
inf

または、C++ 11準拠のコンパイラを使用している場合は、いわゆる汎用参照アプローチを使用できます。これは、参照の折りたたみルールを介して、左辺値と右辺値の両方の参照にバインドできます。

#include <iostream>
using namespace std;

struct Person {
  int age;
  Person(int _age): age(_age) {}
};

template<typename T> // can bind to both lvalue AND rvalue references
void printAge(T&& person) {
   cout << "Age: " << person.age << endl;
}

int main () {
  Person p(50);
  printAge(Person(50));  // works now
  printAge(p);
  return 0;
}

または、C++ 14では、

void printAge(auto&& person) {
   cout << "Age: " << person.age << endl;
}
10
vsoftco