Expr & e1과 Expr e1의 차이가 뭐죠?

ole2000의 이미지

아래와 같은 코드가 있는데..
메인에서 Expr e1 = .. 으로 해주면 잘 됩니다.
근데 Expr & e1으로 하면 error: invalid initialization of non-const reference of type 에러가 나네요.
왜 에러가 나는거죠?

#ifndef _EXPR_H_
#define _EXPR_H_

#include <string>

class Expr
{
public:
	Expr(string s,  bool b) : str(s),value(b) { }
	virtual bool evaluate() const
	{
		return value;
	}

	virtual string description() const
	{
		return str;
	}

	virtual void print(ostream & o) const
	{
		o << str;
	}

private:
	bool value;
	string str;
};

class TRUE : public Expr
{
public:
	TRUE() : Expr("T", true) { }
};

class FALSE : public Expr
{
public:
	FALSE() : Expr("F", false) { }
};

class AND : virtual public Expr
{
public:
	AND(Expr e1, Expr e2) : Expr( ("( "+e1.description()+" ) AND ( "+e2.description()+" )") , e1.evaluate() && e2.evaluate() ) { }
};

#include "Expr.h"

int main() {

    TRUE T;
    FALSE F;

    cout << T << " is " << T.evaluate() << endl;
    cout << F << " is " << F.evaluate() << endl;

    Expr & e1 = AND (T, F); // 에러
    cout << e1 << " is " << e1.evaluate() << endl;
}
doldori의 이미지

non-const 참조형의 초기값은 lvalue이어야 하는데 지금은 그렇지 않으니까요.
int& ri = 0 이 허용되지 않는 것과 마찬가지입니다. 이런 식으로 하면 됩니다.

AND a(T, F);
Expr& e1 = a;

/* or */

const Expr& e1 = AND (T, F);

아, 그리고 Expr 생성자의 인자는 const string& 으로 하는 것이 좋겠습니다.
필요없는 복사를 방지할 수 있으니까요.