簡體   English   中英

C ++通過引用

[英]C++ pass-by-reference

我正在嘗試使用以下簡單代碼進行C ++傳遞引用:

#include <iostream>
int square(int &x)
{
return x*x;
}
int main()
{
std::cout<<"Square of 4 is: "<<square(4)<<std::endl;
return 0;
}

但是,當我嘗試運行它時,得到以下信息:

在此處輸入圖片說明

更新

在基於@Pablo Santa Cruz的答案修改代碼后,出現以下錯誤(我只是捕獲了部分錯誤):

在此處輸入圖片說明

這是為什么?

謝謝。

您不能將臨時變量傳遞給非恆定引用。

使square接受const int &

int square(const int &x)
{
    return x*x;
}

如果期望引用,則不能傳遞常量( 4 )。

必須傳遞一個變量:

int n = 4;
square(n);

話雖如此,您可能想要這樣的東西:

void square(int &x)
{
   x = x*x;
}

不是返回int的函數。

這是因為C ++ 03的第8.5.3 5節:

T1” is initialized by an expression of type “ T2” as follows: 對類型“ T1”的引用由類型“ T2”的表達式初始化,如下所示:
  • 如果初始化表達式
    • T1” is reference-compatible with “ T2,” or 是左值(但不是位字段),並且“ T1”與“ T2”具有參考兼容性,或者
    • T3,” where “ T1” is reference-compatible with “ T3” 92) (this conversion is selected by enumerating the applicable conversion functions (13.3.1.6) and choosing the best one through over- load resolution (13.3)), 具有類類型(即T2是類類型),並且可以隱式轉換為類型“ T3”的左值,其中“ T1”與“ T3” 92引用兼容)(此轉換由列舉適用的轉換函數(13.3.1.6)並通過過載分辨率選擇最佳的轉換函數(13.3)),
    然后在第一種情況下將引用直接綁定到初始化表達式左值,在第二種情況下將引用綁定到轉換的左值結果。 在這些情況下,引用被稱為直接綁定到初始化程序表達式。 [ 注意:普通的左值到右值(4.1),數組到指針(4.2)和函數到指針(4.3)標准轉換是不需要的,因此,當此類直接綁定到左值時完成。 ]
  • shall be const). 否則,引用應為非易失性const類型(即為const)。
    • T1” is reference-compatible with “ T2,” the reference is bound in one of the following ways (the choice is implementation-defined. 如果初始化器表達式是一個右值,T2是類類型,並且“ T1”與“ T2”是引用兼容的,則該引用將通過以下方式之一進行綁定(選擇由實現定義)。
      • 引用綁定到右值表示的對象(請參見3.10)或該對象內的子對象。
      • T2” [sic] is created, and a constructor is called to copy the entire rvalue object into the temporary. 將創建一個類型為“ T2”的臨時文件,然后調用構造函數將整個右值對象復制到該臨時文件中。 引用綁定到臨時項或臨時項中的子對象。
    • T1” is created and initialized from the initializer expression using the rules for a non-reference copy initialization (8.5). 否則,將使用非引用副本初始化(8.5)的規則從初始化程序表達式創建和初始化類型為“ T1”的臨時文件。 然后將引用綁定到臨時目錄。 must be the same cv-qualification as, or greater cv- qualification than, ; 如果T1被參考相關到必須是相同的CV-資格,或更大的CV-資格比 否則,程序格式不正確。

*" refers to the modifiers "const" and "volatile", and "T*" refer to type names. 上面的“ *”是指修飾符“ const”和“ volatile”,而“ T *”是指類型名稱。 = "const", T = "int"), const volatile std::string ( = "const volatile", T = "std::string"), char* ( = "", T = "char*"). 例如, const int =“ const”,T =“ int”), const volatile std::string =“ const volatile”,T =“ std :: string”), char* =“” ,T =“ char *”)。

簡而言之, rvalue只允許綁定到const引用。

更新資料

如果您的square現在返回void(代碼或未發生),則新的錯誤是因為沒有operator<<(std::out&, void)

編譯器為常量4創建一個臨時對象,該對象不能作為非常量引用傳遞給函數。 main創建一個int對象,並將其傳遞給函數,或者通過const-reference或副本采用function參數。

報關單

int square(int& x);

表示函數square可能會更改其參數(盡管實際上不是)。 因此,調用square(4)是荒謬的:程序需要准備好更改數字4。

正如人們已經指出的那樣,您可以更改函數以指定它不會更改其參數:

int square(const int& x); // pass reference to const type
// OR
int square(int x);        // pass by value

或者,您可以使用可以修改的值來調用原始square

int square(int& x);
// ...
int num = 4;
square(num);
// now (as far as the compiler knows) num might no longer be 4!

引用必須是l值-基本上,您可以在賦值語句的左側看到該值。

因此,基本上,您需要首先在main分配一個變量。 然后,您可以將其傳遞到square

引用是另一個變量的別名。 “ 4”不是變量,因此您的引用沒有別名。 因此,編譯器抱怨。

您想要的是:

#include <iostream>
int square(int x)
{
    return(x * x);
}
int main()
{
    std::cout << "Square of 4 is: "<< square(4) << std::endl;
    return 0;
}

您是否注意到我是如何擺脫& int square(int &x) &表示通過引用傳遞。 它需要一個變量。 4square(4)是一個常數。

使用傳遞引用,可以更改x的值:

void square2(int &x)
{
    x = x * x;
    return;
}

現在:

int x = 5;
square2(x);
// x == 25

雖然,我認為您不想要這個。 (您嗎?)第一種方法要好得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM