在 C++ 中使用多个三元运算符调用时,不区分 bool 和 enum 类型重载的函数
Function overloaded by bool and enum type is not differentiated while called using multiple ternary operator in C++
尝试使用条件运算符调用重载函数时遇到一个有趣的问题(只是为了避免多个 if else 条件)
class VirtualGpio
{
typedef enum
{
OUTPUT = 0xC7,
INPUT ,
DIRINVALID
}GpioDirection;
struct pinconfig
{
struct pinmap pin;
GpioPolarity plrty;
bool IsPullupCfgValid;
bool IsTriStCfgValid;
bool IsInputFilterValid;
GpioDirection dic;
gpiolistner fptr; // Callback function pointer on event change
};
};
class factory
{
public:
VirtualGpio *GetGpiofactory(VirtualGpio::pinconfig *cfg,VirtualGpio::GpioAccessTyp acc=VirtualGpio::Pin);
private:
int setCfgSetting(VirtualGpio::pinmap * const getpin, VirtualGpio::GpioDirection const data);
int setCfgSetting(VirtualGpio::pinmap * const getpin, bool const data);
};
int factory::setCfgSetting(VirtualGpio::pinmap * const getpin, VirtualGpio::GpioDirection const data)
{
cout << "It is a Direction overloaded" << endl;
}
int factory::setCfgSetting(VirtualGpio::pinmap * const getpin, bool const data)
{
cout << "It is a bool overloaded" << endl;
}
VirtualGpio* factory::GetGpiofactory(VirtualGpio::pinconfig *cfg,VirtualGpio::GpioAccessTyp acc)
{
VirtualGpio * io = new VirtualGpio();
printf("acc : 0x%X, pin : 0x%x, port : 0x%x\n",acc, cfg->pin.pinno, cfg->pin.portno);
printf("value of expression : 0x%x\n",((acc == VirtualGpio::Pin)? cfg->dic : ((cfg->dic == VirtualGpio::INPUT)?true :false))); <= this prints the right value
if(acc == VirtualGpio::Pin)
setCfgSetting(&cfg->pin,cfg->dic);
else if(cfg->dic == VirtualGpio::INPUT)
setCfgSetting(&cfg->pin,true);
else
setCfgSetting(&cfg->pin,false);
#if 0
if(setCfgSetting(&cfg->pin, ((acc == VirtualGpio::Pin)? cfg->dic : ((cfg->dic == VirtualGpio::INPUT)?true :false))) == ERROR)
{
printf("Error Setting the IO configuration for XRA\n");
}
else
printf("Set IO config successfully\n");
#endif
return io;
}
GetGpiofactory()
中的注释部分#if 0
同上
多个 if-else-if-else 块,但是如果我取消注释 #if0 部分到 #if
1、对于所有可能的输入只有bool版本的重载
函数即 setCfgSetting(VirtualGpio::pinmap * const getpin, bool
const data)
被调用。
下面是我的主要代码。
main()
{
static struct VirtualGpio::pinconfig cfg = {
.pin = {
.location = VirtualGpio::GPIO_ON_GPIOEXP1_TCI,
.pinno = 0,
.portno = -1
},
.plrty = VirtualGpio::active_high,
.IsPullupCfgValid = true,
.IsTriStCfgValid = true,
.IsInputFilterValid = true,
.dic = VirtualGpio::OUTPUT,
.fptr = NULL
};
factory fac;
fac.GetGpiofactory(&cfg);
}
令人惊讶的是,如果我不使用三元运算符而是使用多个 if-else if-else 块,重载函数运行良好。很想知道原因。
那是因为三元运算符的计算结果总是单一类型。您不能使用此运算符 "return" 不同的类型。
当编译器遇到这样的表达式时,他会尝试弄清楚是否可以将整个事物简化为一种类型。如果那不可能,你会得到一个编译错误。
在您的情况下,有一个使用 bool
作为类型的有效选项。因为 cfg->dic
是一个 enum
类型,可以隐式转换为 bool
。如果您使用 and enum class
,您的代码将不再编译,向您显示您的实际问题是什么 (example)。
我也不太明白这种代码有什么好处。在我看来,它使代码更难阅读。如果您担心它们太多,您可以将 ifs
减少到一个:
if(acc == VirtualGpio::Pin)
setCfgSetting(&cfg->pin,cfg->dic);
else
setCfgSetting(&cfg->pin, cfg->dic == VirtualGpio::INPUT);
尝试使用条件运算符调用重载函数时遇到一个有趣的问题(只是为了避免多个 if else 条件)
class VirtualGpio
{
typedef enum
{
OUTPUT = 0xC7,
INPUT ,
DIRINVALID
}GpioDirection;
struct pinconfig
{
struct pinmap pin;
GpioPolarity plrty;
bool IsPullupCfgValid;
bool IsTriStCfgValid;
bool IsInputFilterValid;
GpioDirection dic;
gpiolistner fptr; // Callback function pointer on event change
};
};
class factory
{
public:
VirtualGpio *GetGpiofactory(VirtualGpio::pinconfig *cfg,VirtualGpio::GpioAccessTyp acc=VirtualGpio::Pin);
private:
int setCfgSetting(VirtualGpio::pinmap * const getpin, VirtualGpio::GpioDirection const data);
int setCfgSetting(VirtualGpio::pinmap * const getpin, bool const data);
};
int factory::setCfgSetting(VirtualGpio::pinmap * const getpin, VirtualGpio::GpioDirection const data)
{
cout << "It is a Direction overloaded" << endl;
}
int factory::setCfgSetting(VirtualGpio::pinmap * const getpin, bool const data)
{
cout << "It is a bool overloaded" << endl;
}
VirtualGpio* factory::GetGpiofactory(VirtualGpio::pinconfig *cfg,VirtualGpio::GpioAccessTyp acc)
{
VirtualGpio * io = new VirtualGpio();
printf("acc : 0x%X, pin : 0x%x, port : 0x%x\n",acc, cfg->pin.pinno, cfg->pin.portno);
printf("value of expression : 0x%x\n",((acc == VirtualGpio::Pin)? cfg->dic : ((cfg->dic == VirtualGpio::INPUT)?true :false))); <= this prints the right value
if(acc == VirtualGpio::Pin)
setCfgSetting(&cfg->pin,cfg->dic);
else if(cfg->dic == VirtualGpio::INPUT)
setCfgSetting(&cfg->pin,true);
else
setCfgSetting(&cfg->pin,false);
#if 0
if(setCfgSetting(&cfg->pin, ((acc == VirtualGpio::Pin)? cfg->dic : ((cfg->dic == VirtualGpio::INPUT)?true :false))) == ERROR)
{
printf("Error Setting the IO configuration for XRA\n");
}
else
printf("Set IO config successfully\n");
#endif
return io;
}
GetGpiofactory()
中的注释部分#if 0
同上
多个 if-else-if-else 块,但是如果我取消注释 #if0 部分到 #if
1、对于所有可能的输入只有bool版本的重载
函数即 setCfgSetting(VirtualGpio::pinmap * const getpin, bool
const data)
被调用。
下面是我的主要代码。
main()
{
static struct VirtualGpio::pinconfig cfg = {
.pin = {
.location = VirtualGpio::GPIO_ON_GPIOEXP1_TCI,
.pinno = 0,
.portno = -1
},
.plrty = VirtualGpio::active_high,
.IsPullupCfgValid = true,
.IsTriStCfgValid = true,
.IsInputFilterValid = true,
.dic = VirtualGpio::OUTPUT,
.fptr = NULL
};
factory fac;
fac.GetGpiofactory(&cfg);
}
令人惊讶的是,如果我不使用三元运算符而是使用多个 if-else if-else 块,重载函数运行良好。很想知道原因。
那是因为三元运算符的计算结果总是单一类型。您不能使用此运算符 "return" 不同的类型。
当编译器遇到这样的表达式时,他会尝试弄清楚是否可以将整个事物简化为一种类型。如果那不可能,你会得到一个编译错误。
在您的情况下,有一个使用 bool
作为类型的有效选项。因为 cfg->dic
是一个 enum
类型,可以隐式转换为 bool
。如果您使用 and enum class
,您的代码将不再编译,向您显示您的实际问题是什么 (example)。
我也不太明白这种代码有什么好处。在我看来,它使代码更难阅读。如果您担心它们太多,您可以将 ifs
减少到一个:
if(acc == VirtualGpio::Pin)
setCfgSetting(&cfg->pin,cfg->dic);
else
setCfgSetting(&cfg->pin, cfg->dic == VirtualGpio::INPUT);