C++ 发送预期获取引用的对象时发生编译错误

C++ 发送预期获取引用的对象时发生编译错误,c++,compilation,pass-by-reference,C++,Compilation,Pass By Reference,我有一小段没有编译的代码,我想知道为什么push(newx)会出现问题 在此之前,我想问一下新的X(没有标识符)到底意味着什么?它是否创建了一个没有标识符名称的对象X?它完全通过构造函数了吗 第二, 我可能不理解整个概念,但是push是一个模板类,对吗? 因为它包含一个静态T堆栈,所以类型T是一致的,并且一旦发送了一个特定的参数(第一个参数,在本例中为int x),就不能更改它。对吗 第三,, 在我的第二个问题之后,如果它是正确的,那么为什么push(y)不像push(newx)那样标记编译器错

我有一小段没有编译的代码,我想知道为什么push(newx)会出现问题

在此之前,我想问一下新的X(没有标识符)到底意味着什么?它是否创建了一个没有标识符名称的对象X?它完全通过构造函数了吗

第二,

我可能不理解整个概念,但是push是一个模板类,对吗? 因为它包含一个静态T堆栈,所以类型T是一致的,并且一旦发送了一个特定的参数(第一个参数,在本例中为int x),就不能更改它。对吗

第三,, 在我的第二个问题之后,如果它是正确的,那么为什么push(y)不像push(newx)那样标记编译器错误呢?我的意思是,x是int类型,y是引用类型

如果有人能为我澄清,我将不胜感激

谢谢,这是:

    #include <iostream>

    using namespace std;

    template <class T>
    void push(T &t) {
    static const int CAPACITY = 20;
    static T stack[CAPACITY];
    static int size = 0;
    stack[size++] = t;
    cout << size;
    };
   class X {};

   void main()
   {
   int x = 3;
   int &y = x;
   push(x);
   push(new X);
   push(y);
 }
#包括
使用名称空间std;
样板
无效推力(T&T){
静态常数int容量=20;
静态T堆栈[容量];
静态int size=0;
堆栈[size++]=t;
库特
我想知道为什么推(新X)会成为问题的更具体的原因

因为您将模板函数参数的类型声明为对
T
的非常量左值引用。为了帮助程序员避免错误的代码语言,不允许将临时变量绑定到非常量左值引用。在您的情况下:

new X
返回类型为
X*
的临时值(指针指向X),您的模板函数参数类型
T
在本例中推导为
X*
,而
T
现在是对
X*
X*&
的左值引用,但语言不允许临时绑定到左值引用hense编译错误。第二种情况在逻辑上与此代码相同:

 void pushX( X *&t ); // pushX accepts reference to pointer to X

 pushX( new X ); // you cannot bind a temporary returned by `new X` to lvalue reference `t`
如果您使用像
int
这样的简单类型,可能更容易理解:

int function_returns_int();

void push_int( int &ri );


push_int( function_returns_int() ); // compilation error, function_returns_int() returns temporary
如果将指针存储在变量中并使其非临时性,则可以编译代码:

int main()    // main() must have return type int not void
{
   int x = 3;
   int &y = x;
   push(x);
   X *px = new X;
   push(px);
   push(y);
   delete px;
}
但很可能你选择了错误的论点类型

有关引用的详细信息,以及为什么可以传递
int&y
以及为什么
t
在本例中不是引用的引用,您可以找到


注意:如果要编译代码(例如,将
t
的类型更改为const reference)将导致内存泄漏,但这超出了您的问题范围。

gold push是一个模板函数。gold new运算符返回指向动态创建对象的指针。请每个问题回答一个问题。如果您的代码未编译,请显示编译器错误(第一个就足够了),并指向生成它的行。对于
push(y)
,谷歌“引用崩溃”如果可以的话,再问一个问题:为什么我要将它改为push(*(新X))它可以编译吗?我只是尊重指针,但它不是仍然是一个r值/临时值吗?不,当你取消引用指针时,取消引用的结果是l值,尽管指针本身是prvalue,这就是语言的工作方式。它试图帮助你避免错误,但有很多方法可以让你措手不及。