[英]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”的表達式初始化,如下所示:
- 如果初始化表達式
然后在第一種情況下將引用直接綁定到初始化表達式左值,在第二種情況下將引用綁定到轉換的左值結果。 在這些情況下,引用被稱為直接綁定到初始化程序表達式。 [ 注意:普通的左值到右值(4.1),數組到指針(4.2)和函數到指針(4.3)標准轉換是不需要的,因此,當此類直接綁定到左值時完成。 ]
- 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)),
- 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)
? &
表示通過引用傳遞。 它需要一個變量。 在4
在square(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.