最近,我一直在做一个巨大的重构,其中我更改了很多代码以返回布尔值,而不是明确的返回代码。为了帮助这种重构,我决定在可能的情况下依靠编译器,告诉我需要更改代码的地方。我通过介绍以下课程来做到这一点(请参阅此处有关此操作的低点):

///
/// Typesafe boolean class
///
class TypesafeBool
{
private:
    bool m_bValue;
    struct Bool_ { 
        int m_nValue; 
    };
    typedef int Bool_::* bool_;
    inline bool_ True() const { return &Bool_::m_nValue; }
    inline bool_ False() const { return 0; }

public:
    TypesafeBool( const bool bValue ) : m_bValue( bValue ){}
    operator bool_() const { return m_bValue ? True() : False(); }
};

现在,而不是使用普通 bool 类型为返回类型,我使用了此类,这意味着我再也无法编译这样的东西了:

TypesafeBool SomeFunction();
long result = SomeFunction(); // error

太好了:它通过让编译器为我做很多辛苦工作,使重构在巨大的代码库中可以管理。因此,现在我已经完成了重构,我非常想让这堂课闲逛并继续使用它,因为它为我们提供了额外的安全水平 bool 类型不。

但是,有一个“问题”阻止我这样做。目前,我们大量使用 三元操作员 在我们的代码中,问题在于,如果没有明确的演员阵容,它与该新类不兼容:

TypesafeBool result = ( 1 == 2 ? SomeFunction() : false ); // error: different types used
TypesafeBool result = ( 1 == 2 ? SomeFunction() : (TypesafeBool)false );

如果我可以“解决”此问题,以便我可以以无缝的方式使用我的课程,那么我可能会在整个代码库中使用它。有人知道解决这个问题的解决方案吗?还是做我想做的事情是不可能的?

有帮助吗?

解决方案

      class CCastableToBool
      {  
      public:
         // ...
         operator bool() const
         {  
           //...
           {
              return true;
           } 
           //...
           return false;
         }  
      private:
         // ...
      }; 

但是要当心,在C ++中,可以将可以铸入布尔的课程被认为是非常危险的。您被警告:-)

您可以在那里阅读此书, SafeBool

您应该在所有三元测试中明确调用typeafebool :: true()。

TypesafeBool result = ( 1 == 2 ? SomeFunction().True() : false );

其他提示

在条件操作员的背景下,表达式的类型是 常见类型 在最后两个操作数中。确定这种常见类型的完整规则有点复杂,但是您的情况恰好是微不足道的:如果两个可能的返回值之一是类类型,则另一个值必须具有相同的类,并且公共类型显然也是班级。

这意味着,如果操作数之一是typesafebool,那么另一个也必须是。

现在,您真正要解决的问题以前已经解决了。诀窍不是提供课程。而是使用Typedef。例如,请参见 安全的布尔.

我不知道一种无缝的方式,三元运营商对其使用有一些限制...

但是,为什么不定义两个常数?

TypesafeBool const True = TypesafeBool(true);
TypesafeBool const False = TypesafeBool(false);

进而:

TypesafeBool result = ( 1 == 2 ? SomeFunction() : False );

当然,这有点不合常规,因为我在大写字母上避免重复使用保留的词:)

是否有可能使typesafebool的构造函数显式?当然,现在的用法必须

TypesafeBool result( 1 == 2 ? b : false );

您能否使用将布尔作为外部参数的作业运算符以及采用Typesafebool的分配操作员?可能是可以尝试的东西...

不错的尝试,但是如果您的代码库很大,则最好使用静态检查器(例如PC-lint)来寻找隐式bool <-> int转换。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top