我最近一直在做一个巨大的重构,我正在改变我的很多代码来返回布尔值而不是显式的返回代码。为了帮助这种重构,我决定尽可能地依赖编译器,让它告诉我需要更改代码的地方。我通过介绍以下类(see here for the lowdown on how this works):
来完成此操作///
/// 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
类型没有。
然而,有一个“问题”阻止我这样做。目前我们在代码中大量使用ternary operator,问题是如果没有显式的强制转换,它与这个新类不兼容:
TypesafeBool result = ( 1 == 2 ? SomeFunction() : false ); // error: different types used
TypesafeBool result = ( 1 == 2 ? SomeFunction() : (TypesafeBool)false );
如果我可以“解决”这个问题,以便我可以无缝地使用我的类,我可能会继续在整个代码库中使用它。有谁知道这个问题的解决方案?或者只是不可能做我想做的事情?
答案 0 :(得分:2)
在条件运算符的上下文中,表达式的类型是最后两个操作数的公共类型。确定这种常见类型的完整规则有点复杂,但是你的情况恰好是微不足道的:如果两个可能的返回值中的一个是类类型,则另一个值必须具有相同的类,并且公共类型显然也是类。
这意味着如果其中一个操作数是TypesafeBool,那么另一个操作数也必须是。
现在你真正试图解决的问题已经解决了。诀窍不是提供课程;而是使用typedef。例如,请参阅safe bool。
答案 1 :(得分:1)
我不知道无缝的方式,三元运算符对其使用有一些限制......
但是,为什么不定义两个常量?
TypesafeBool const True = TypesafeBool(true);
TypesafeBool const False = TypesafeBool(false);
然后:
TypesafeBool result = ( 1 == 2 ? SomeFunction() : False );
当然,由于我使用大写以避免重复使用保留字,因此它有点不正统:)
答案 2 :(得分:1)
class CCastableToBool
{
public:
// ...
operator bool() const
{
//...
{
return true;
}
//...
return false;
}
private:
// ...
};
但要注意,在C ++中,拥有一个可以转换为bool的类被认为是非常危险的。你被警告: - )
你可以在那里阅读,SafeBool
您应该在所有三元测试中明确地调用TypesafeBool :: True()。
TypesafeBool result = ( 1 == 2 ? SomeFunction().True() : false );
答案 3 :(得分:0)
是否可以使TypesafeBool的构造函数显式化?当然,现在必须使用
TypesafeBool result( 1 == 2 ? b : false );
答案 4 :(得分:0)
你能使用一个赋值操作符来接受一个bool作为外部参数,还有一个接受TypesafeBool的操作符?可能需要尝试一下......
答案 5 :(得分:0)
很好的尝试,但是如果您的代码库很大,那么最好使用静态检查程序(如PC-Lint)来查找隐式bool< - > int转换。