私は、次のクラスがあります。コンストラクタは、常に代わりに、明示的な変換演算子の使用されている
template <typename T1>
class Foo {
public:
Foo(T1* obj) : obj(obj) {}
template <typename T2>
Foo(const Foo<T2>& other) : obj(other.obj) {}
template <typename T2>
explicit operator Foo<T2>() {
return Foo<T2>(static_cast<T2*>(obj));
}
T1* obj;
};
二コンストラクタの意図はFoo<Y>
からFoo<X>
からの暗黙的な変換はからY*
への暗黙的な変換のときに限り許可されていることです許可されています。
変換演算子はY*
からからの明示的な変換を使用してFoo<Y>
にFoo<X>
からの明示的な変換を可能にするために存在します。
しかし、変換演算子は決して使用されないことに気付きました。コンパイラは、明示的キャストを実行しても、常に2番目のコンストラクタを使用します。これは、基になる型の暗黙の変換が不可能な場合にエラーを引き起こします。
上記のクラスをテストするには、次のコードを使用できます。
class X {};
class Y : public X {};
int main() {
Y obj;
Foo<Y> y(&obj);
Foo<X> x = y; // implicit cast works as expected.
// y = x; // implicit conversion fails (as expected).
// y = static_cast<Foo<Y>>(x); // conversion fails because constructor is
// called instead of conversion operator.
}
コンパイラに明示的な変換に変換演算子を使用させる方法はありますか?
コンストラクタ 'explicit'してください。 – user0042
私は単なる明示的な変換/キャストをポインタに静的なキャストを引き起こすために行かないだろう。 (Foo 'をテンプレート関数に渡すと、間違って' Foo 'を無効な方法で変換してしまいます)。代わりに、私は明らかに静的なfooキャストである関数を持っているので、あなたは危険の点を見ることができ、それが意味するときにのみ起こります。 –
Yakk