クラスのクラスをブールのように扱わせることはできますか?
-
30-09-2019 - |
質問
私は最近、明示的な返品コードの代わりにブール付けを返すために私のコードの多くを変更していた巨大なリファクタリングを行ってきました。このリファクタリングを支援するために、可能な限りコンパイラに頼ることにし、コードを変更する必要がある場所を教えてもらうことにしました。私は次のクラスを紹介することでこれを行いました(これがどのように機能するかについては、こちらをご覧ください):
///
/// 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
タイプはありません。
ただし、私がこれを行うことを妨げている「問題」が1つあります。現時点では、私たちは大いに利用しています 三元演算子 私たちのコードでは、問題は、明示的なキャストなしでこの新しいクラスと互換性がないことです。
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
すべての三元テストで、TapeAfebool :: true()を明示的に呼び出す必要があります。
TypesafeBool result = ( 1 == 2 ? SomeFunction().True() : false );
他のヒント
条件演算子のコンテキストでは、式のタイプは 共通タイプ 最後の2つのオペランドのうち。この一般的なタイプを決定するための完全なルールは少し複雑ですが、あなたのケースはたまたま些細なことです。2つの可能な返品値の1つがクラスタイプである場合、他の値は同じクラスを持ち、共通タイプは明らかにそれである必要がありますクラス。
つまり、オペランドの1つがTypesafeboolである場合、もう1つも同様になければならないことを意味します。
今、あなたが本当に解決しようとしている問題は以前に解決されました。トリックはクラスを提供しないことです。代わりに、typedefを使用します。たとえば、参照してください 安全なブール.
私はシームレスな態度について知りません、三元オペレーターはその使用にいくつかの制限を持っています...
ただし、2つの定数を定義してみませんか?
TypesafeBool const True = TypesafeBool(true);
TypesafeBool const False = TypesafeBool(false);
その後:
TypesafeBool result = ( 1 == 2 ? SomeFunction() : False );
もちろん、私は予約された言葉を再利用することを避けるために大文字で遊んでいるので、それは少し非正統的です:)
TypeSafeboolのコンストラクターを明示的にする可能性はありますか?もちろん、今では使用が必要です
TypesafeBool result( 1 == 2 ? b : false );
Boolを外部引数として取得する割り当てオペレーターと、TypeSafeboolを使用する課題オペレーターを使用できますか?試してみるものかもしれません...
いい試してみてくださいが、コードベースが大きい場合は、おそらくPC-LINTなどの静的チェッカーを使用して、代わりに暗黙のbool <-> INT変換を探す方が良いでしょう。