我试图重载一些函数来处理几种数据类型。当我将变量作为参数传递时,这是微不足道的,因此:
void fnc(int32_t d){
Serial.println((String) "int32 = " + d);
}
void fnc(char* d){
Serial.println((String) "string = " + d);
}
void fnc(bool d){
if(d){ Serial.println((String) "bool = " + "true"); }
else{ Serial.println((String) "bool = " + "false"); }
}
void fnc(float d){
Serial.println((String) "float = " + d);
}
int32_t anInt = 29339222;
char* aStr = "baloney";
bool aBool = false;
float aFloat = 3.1415;
void setup() {
Serial.begin(9600);
fnc(anInt);
fnc(aStr);
fnc(aBool);
fnc(aFloat);
}
(Note,这是在Arduino上,因此setup()而不是main()。
结果如您所料:
29339222
string = baloney
bool = false
浮点数= 3.14
现在,我需要传递文字值和变量,像这样:
fnc(8728787);
fnc("spamoney");
fnc(true);
fnc(2.718);
编译器抱怨最后一行调用fnc(2.718):
sketch_apr1a.ino:34:12: error: call of overloaded 'fnc(double)' is ambiguous
fnc(2.718);
我想这是因为作为一个字面量,参数没有向编译器提供类型信息。值的实际位可以被解释为任何4字节类型(在Arduino上float是4字节),int32_t是4字节类型。
所以,有几个问题:
1.为什么编译器在使用8728787作为参数时没有出现类似的问题呢?这应该也是模棱两可的,不是吗?
1.我怎样才能做到这一点呢?有没有办法把所有这些类型都作为变量和文字接受呢?
注意:我不想使用模板函数,因为我需要用不同的算法处理不同的类型。
注意:我已经解决了这个问题,现在通过简单地创建多个函数,即fncInt,fncStr,fncBool等。
注意注意注意:这将是一个库的一部分。我也想避免强迫使用它的人做fnc((float)2.718),原因和前面的注解一样。也许这很傻。我不知道。
更新:非常感谢Miles Budnik和273 K的帮助。如果我将func(float d)更改为func(double d),它确实可以编译。
但是,如果我尝试传递一个int,它又会失败。
int anInt2 = 12;
int32_t anInt = 29339222;
float aFloat = 3.1415;
void setup() {
Serial.begin(9600);
fnc(anInt);
fnc(aFloat);
fnc(8728787);
fnc(2.718);
fnc(anInt2);
}
sketch_apr1a.ino:28:13:错误:调用重载'fnc(int&)'是模糊的fnc(anInt 2);
另外,如果我把int 32改为int 64,同样会失败,同样是在双精度字面值上。
void fnc(int64_t d){
//Serial.println((String) "int32 = " + d);
}
int64_t anInt = 29339222;
float aFloat = 3.1415;
void setup() {
Serial.begin(9600);
fnc(anInt);
fnc(aFloat);
fnc(8728787);
fnc(2.718);
fnc(anInt2);
}
sketch_apr1a.ino:27:14:错误:调用重载的'fnc(long int)'是不明确的fnc(8728787);^
我很感激你的建议,我确实试着从书中理解这一点;恐怕我对整件事都很困惑。谢谢你的帮助。
1条答案
按热度按时间flvtvl501#
您的问题是文本
2.718
的类型为double
,而不是float
,并且没有fnc(double)
重载。C++允许在执行重载解析时隐式添加一个内置转换和一个用户定义转换。有从double
到int32_t
、bool
、int32_t
、bool
、bool
、bool
、bool
、bool
、bool
、bool
、bool
、bool
、bool
、bool
、bool
、bool
、bool
、bool
、bool
、bool
、bool
、x1n1x和float
,编译器认为它们中没有一个比其他任何一个“更好”,因为它们都是有损转换。因此,调用是模糊的,因为它不知道你想调用fnc(int32_t)
,fnc(bool)
还是fnc(float)
。如果你让你的浮点重载接受一个
double
而不是一个float
,那么就会有一个完全匹配,它被认为比需要转换的匹配“更好”,所以会被选择。还要注意,
float
到double
的转换也被认为比提到的其他转换“更好”,因为它是无损的,而其他转换是有损的,所以对于fnc(aFloat)
的调用,编译器也会选择fnc(double)
而不是fnc(int32_t)
或fnc(bool)
。或者,您可以将
f
后缀附加到浮点字面值以显式地使其成为float
。例如,fnc(2.718f)
不会有二义性,因为它与fnc(float)
完全匹配。1.为什么编译器在使用8728787作为参数时没有出现类似的问题呢?这应该也是模棱两可的,不是吗?
这有点复杂。在Arduino上,
int
可以是16位或32位,具体取决于确切的板。8728787
的类型将是int
(如果int
是32位)或long int
(如果int
是16位),因为8728787
太大,无法用16位表示。int32_t
将是int
(如果int
是32位)或long int
(如果int
是16位)的别名。在任何一种情况下,
8728787
的类型都将与int32_t
完全匹配。由于它是完全匹配,因此fnc(int32_t)
将优先于其他选项。如果你试图向
fnc
传递一个64位整数,你会得到与double
到float
的情况相同的二义性。例如,下面的代码是二义性的,原因与double
调用相同: