代码之家  ›  专栏  ›  技术社区  ›  Srinivasan

在C中使用多个三元运算符调用时,不会区分bool和enum类型重载的函数++

  •  -5
  • Srinivasan  · 技术社区  · 7 年前

    尝试使用条件运算符调用重载函数时遇到了一个有趣的问题(只是为了避免多个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;
    
    }
    

    已评论的部分 #if 0 在里面 GetGpiofactory() 同上 多个if else if else块,但如果我将#if0部分取消注释为#if 1,对于所有可能的输入,仅限重载的布尔版本 功能,即 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块,重载函数就会工作得很好。好奇地想了解原因。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Sebastian Stern    7 年前

    这是因为三元运算符总是计算为单一类型。不能使用此运算符“返回”不同的类型。

    当编译器遇到这样一个表达式时,他会试图弄清楚是否可以将整个过程简化为一种类型。如果不可能,则会出现编译错误。

    在您的情况下,有一个有效的选项使用 bool 作为一种类型。因为 cfg->dic 是一个 enum 可隐式转换为的类型 布尔 . 如果您使用和 enum class 您的代码将不再编译,从而显示您的实际问题是什么( example ).

    我也不知道这种代码的优点是什么。在我看来,这使得代码更难阅读。你可以减少 ifs 如果你担心的人太多,那就给一个人:

    if(acc == VirtualGpio::Pin)
      setCfgSetting(&cfg->pin,cfg->dic);
    else
      setCfgSetting(&cfg->pin, cfg->dic == VirtualGpio::INPUT);