コンストラクターをint
とでオーバーロードしようとしchar *
ます。次に、との呼び出しにあいまいさがあります0
。これに対する回避策/解決策はありますか?
CBigInt (unsigned int);
CBigInt (const char *);
問題は次のようになっています0
:
CBigInt a;
// some more code
a *= 0;
回答ありがとうございます。
コンストラクターをint
とでオーバーロードしようとしchar *
ます。次に、との呼び出しにあいまいさがあります0
。これに対する回避策/解決策はありますか?
CBigInt (unsigned int);
CBigInt (const char *);
問題は次のようになっています0
:
CBigInt a;
// some more code
a *= 0;
回答ありがとうございます。
コンストラクターの1つを明示的にします。渡されたタイプが完全に一致する場合にのみ使用されます。
CBigInt (unsigned int);
explicit CBigInt (const char *);
「explicit」キーワードを使用できます。
explicit CBigInt(const char *);
これを使用して、引数をconst char *に明示的にキャストする必要があります。そうしないと、CBigInt(unsigned)が実行されます。
「明示的な」アプローチは機能しますが、将来の開発者をサポートするために直感的ではない可能性があります。このような場合、私が取り組んだ以前のプロジェクトでは、静的ファクトリメソッドを使用しました。プライベートのデフォルトコンストラクターがあり、静的ファクトリのメンバーを明示的に初期化します。何かのようなもの:
class CBigInt {
public:
...
static CBigInt fromUInt(unsigned int i) {
CBigInt result;
result.value=i;
return result;
}
static CBigInt fromCharPtr(const char* c) {
CBigInt result;
result.value=parse(c);
return result;
}
...
private:
CBigInt () {}
/*some internal type here*/ value;
};
このアプローチにより、コンパイラーだけでなく、後でコードをサポートするコンパイラーのあいまいさもなくなります。
この場合、コンストラクター(コンストラクターが取る)は数値(クラスexplicit
がモデル化する)をモデル化しないと思うので、コンストラクターもお勧めします。CBigInt
そのような場合は、そのexplicit
ために設計されたものです。
ただし、これは直接初期化が使用されている場合には機能しません
struct A {
CBigInt n;
A():n(0) { } // ambiguity again
};
一般に、explicit
内部のあいまいさを解決するために使用しないでください。あるタイプから別のタイプへの変換を禁止するためにのみ使用する必要がありますが、コンストラクターよりも別のコンストラクターを優先するためには使用しないでくださいexplicit
。実際、新しいC ++ 0xの統一初期化では、コピー初期化コンテキストのコンストラクターは無視されません。explicit
CBigInt f() {
return { 0 }; // still ambiguous
}
CBigInt b = { 0 }; // still ambiguous
均一な初期化のルールは次のとおりです。両方のコンストラクターが考慮されますが、明示的なコンストラクターが選択された場合、初期化の形式が正しくありません。
リテラル0
はint
です。すべての整数型を受け入れることができるようにしたい場合は、少なくともtakeingint
コンストラクターを追加する必要があります。よりも小さい整数型にはオーバーロードを追加する必要はありません。これらの型は他の整数変換またはポインターよりもint
優先されるためです。int
オーバーロードがあると仮定するとint
、残りの整数型にオーバーロードを追加する必要があります。使用可能な場合は、それを使用しlong long
ますunsigned long long
。そうすれば、あいまいさはもう発生しなくなります。
CBigInt (int);
CBigInt (unsigned int);
CBigInt (long);
CBigInt (unsigned long);
// CBigInt (long long);
// CBigInt (unsigned long long);
explicit CBigInt (const char *);