[英]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.