私が尋ねた最後の質問は、別のことを理解しようとしたときにつまずいたものでした... 私も理解できません(私の日ではありません)。
これは非常に長い質問文ですが、少なくとも、この質問が私だけでなく多くの人に役立つことを願っています.
私が持っているコードは次のとおりです。
template <typename T> class V;
template <typename T> class S;
template <typename T>
class V
{
public:
T x;
explicit V(const T & _x)
:x(_x){}
V(const S<T> & s)
:x(s.x){}
};
template <typename T>
class S
{
public:
T &x;
explicit S(V<T> & v)
:x(v.x)
{}
};
template <typename T>
V<T> operator+(const V<T> & a, const V<T> & b)
{
return V<T>(a.x + b.x);
}
int main()
{
V<float> a(1);
V<float> b(2);
S<float> c( b );
b = a + V<float>(c); // 1 -- compiles
b = a + c; // 2 -- fails
b = c; // 3 -- compiles
return 0;
}
式 1 と 3 は完全に機能しますが、式 2 はコンパイルされません。
私が正しく理解していれば、何が起こるか:
式1
- cは
const
、標準の変換シーケンス (修飾変換が 1 つだけで構成される) を使用して暗黙的に変換されます。 V<float>(const S<T> & s)
が呼び出され、オブジェクトが生成したテンポラルが生成されます (これをtconst V<float>
と呼びましょう)。これは一時的な値であるため、すでに const 修飾されています。- aはcと同様に const に変換されます。
operator+(const V<float> & a, const V<float> & b)
が呼び出され、 qconst V<float>
と呼べるタイプのテンポラルが生成されます。- デフォルト
V<float>::operator=(const & V<float>)
は呼び出されます。
私はここまで大丈夫ですか?私が最も微妙な間違いを犯した場合でも、私に知らせてください.暗黙のキャストについてできるだけ深く理解しようとしています...
式 3
- cは に変換され
V<float>
ます。そのために、ユーザー定義の変換シーケンスがあります:
1.1. 最初の標準変換:修飾変換S<float>
を介して。 1.2. ユーザー定義の変換:コンストラクター経由。 1.3秒基準換算:経由資格換算へ。const S<float>
const S<float>
V<float>
V<float>(const S<T> & s)
V<float>
const V<float>
- デフォルト
V<float>::operator=(const & V<float>)
は呼び出されます。
式2?
私が理解していないのは、なぜ 2 番目の式に問題があるのかということです。次のシーケンスができないのはなぜですか?
- cは に変換され
V<float>
ます。そのために、ユーザー定義の変換シーケンスがあります:
1.1. 初期標準変換:修飾変換S<float>
を介して。 1.2. ユーザー定義の変換:コンストラクター経由。 1.3。最終標準変換:資格変換 を介して。const S<float>
const S<float>
V<float>
V<float>(const S<T> & s)
V<float>
const V<float>
- 手順 2 ~ 6 は式 1 の場合と同じです。
C++ 標準を読んだ後、私は次のように言いました。おそらく問題は 13.3.3.1.2.3 に関係しています! どの州:
ユーザー定義の変換がテンプレート変換関数によって指定されている場合、2 番目の標準変換シーケンスは完全一致ランクでなければなりません。
しかし、資格変換には完全一致ランクがあるため、それは当てはまりません...
本当に手がかりがない...
さて、あなたが答えを持っているかどうかにかかわらず、ここまで読んでくれてありがとう:)