[英]c++ implicit conversion rules
我試圖理解常規或成員函數調用中c ++自動和顯式轉換的規則。 我編寫了以下代碼,但編譯失敗:
#include <iostream>
#include <string>
using namespace std;
class testExplicit {
public:
int intval;
short shortval;
double doubleval;
char charval;
string strval;
testExplicit(int a1, short a2, double a3, char a4, string& a5):
intval(a1),shortval(a2),doubleval(a3),charval(a4),strval(a5){}
void getVal(int& a) { a = intval; cout << "IntVal\n"; }
// void getVal(short& a) { a = shortval; cout << "Short Val\n"; }
// void getVal(double& a) { a = doubleval; cout << "Double Val\n"; }
// void getVal(char& a) { a = charval; cout << "Char Val\n"; }
// void getVal(string& a) { a = strval; cout << "String Val\n"; }
};
int main( int argc, char **argv ) {
string s ("test Str");
testExplicit test (100,10,10.05,5,s);
int i;
char c;
double d;
short f;
test.getVal(i);
test.getVal(c);
test.getVal(d);
test.getVal(f);
return 0;
}
但是,我可以得出結論,函數只需要精確的匹配參數嗎? 我記得讀過自動轉換是根據轉換規則發生的。 有些人可以對正確的規則有所了解嗎?
這是錯誤:
test.cpp: In function 'int main(int, char**)':
test.cpp:38: error: no matching function for call to 'testExplicit::getVal(char&)'
test.cpp:17: note: candidates are: void testExplicit::getVal(int&)
test.cpp:39: error: no matching function for call to 'testExplicit::getVal(double&)'
test.cpp:17: note: candidates are: void testExplicit::getVal(int&)
test.cpp:40: error: no matching function for call to 'testExplicit::getVal(short int&)'
test.cpp:17: note: candidates are: void testExplicit::getVal(int&)
謝謝
void getVal(int& a);
此函數通過引用獲取int
。 你必須傳遞一個int
。 這類似於你有一個功能的方式
void getVal(int* a);
你需要傳遞一個指向int
的指針(不是指向short
或任何其他類型的指針)。
這樣做的一個原因是您可以從函數中修改int
。 為了允許您將另一種類型的對象(例如, short
)傳遞給此函數,必須在運行時創建short
類型的臨時對象,並且必須傳遞對該臨時對象的引用。
這可能不太理想,因為您可能會意外地最終傳遞錯誤類型的對象(例如, short
)並期望它被函數修改,而實際上int
類型的臨時副本將被函數修改,而不是原來的short
。
但是,您可以將const引用綁定到臨時對象,因此如果您的函數被聲明為
void getVal(const int& a);
你可以將任何可轉換為int
類型傳遞給它。 這是有道理的,因為函數不能修改引用的對象(因為它是一個const引用),所以“oops,我不小心修改了一個臨時對象”問題不存在。
轉換時也可以進行轉換,但這也是有意義的:當你按值傳遞時,無論如何都必須復制(通過值傳遞給函數的副本),因此轉換可以作為該副本的一部分。
問題是如果需要隱式轉換,則會創建一個臨時變量。 您不能對臨時變量進行非const引用,因此您需要使您的成員函數為void getVal(const int &a)
或void getVal(int a)
。
應避免隱式轉換。 C ++是一種強類型語言,為您希望接受的類型創建函數,使用模板或將類型顯式轉換為其他類型等等要好得多。
構造函數轉換或使用static_cast<>
, dynamic_cast<>
或reinterpret_cast<>
是一些選項,具體取決於您需要將類型從一個轉換為另一個時的情況。
模板可以讓您更輕松地處理多種類型。
template<typename T>
void getVal(const T& a)
{
// do something
}
通過引用傳遞意味着,為相同類型創建別名。 所以嘗試將void getVal(int& a)
更改為void getVal(int a)
,以便為不同的傳遞參數類型的其他函數調用工作
通過創建rvalue(臨時)來完成隱式轉換,並且rvalues不能綁定到非const引用。 這就是它無法正常工作的原因。 另一方面,如果您更改簽名以通過值或常量引用獲取參數,那么它將起作用:
void f( int a ) { std::cout << a << std::endl; }
void g( const int& b ) { std::cout << b << std::endl; }
int main() {
char c = 'a'; // note that this the ASCII value of 'a'
f( c );
g( c );
short s = 4;
f( s );
g( s );
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.