互いに自由に変換できるようにしたい一連の型があります。次のおもちゃの例を考えてみましょう。
struct A {
int value;
A(int v) : value(v) { }
};
struct B {
int value;
B(int v) : value(v) { }
B(A a) : value(a.value) { }
operator A() const { return A(value); }
};
struct C {
int value;
C(int v) : value(v) { }
C(A a) : value(a.value) { }
C(B b) : value(b.value) { }
operator B() const { return B(value); }
operator A() const { return A(B(*this)); } // <-- ambiguous
};
int main(int argc, const char** argv) {
C c(5);
A a(3);
a = c;
}
ご覧のとおり、キャスト コンストラクターを使用して以前のすべての型から変換可能になるように後続の各型を定義し、キャスト演算子を使用して以前のすべての型に変換可能になるように定義しようとしています。C::operator A
残念ながら、 gcc 4.7 によるとの定義があいまいであるため、これは意図したとおりには機能しません。
In member function ‘C::operator A() const’:
19:40: error: call of overloaded ‘B(const C&)’ is ambiguous
19:40: note: candidates are:
9:3: note: B::B(A)
6:8: note: constexpr B::B(const B&)
6:8: note: constexpr B::B(B&&)
表現を変えてstatic_cast<A>(static_cast<B>(*this))
も何も変わりません。この行を完全に削除すると、 にエラー メッセージが表示されます。これはmain
、暗黙的な変換シーケンスでは複数のユーザー定義変換を使用できないためです。私のおもちゃの例では、 からC
への変換を直接実行できA
ましたが、実際のアプリケーションでは、これを行うと多くの重複コードが発生するため、他の変換演算子を再利用するソリューションが本当に必要です。
では、変換コードを複製することなく、自由に相互変換可能な 3 つの型のセットを取得するにはどうすればよいでしょうか?