const でない左辺値参照 ( など) は、左辺値IUnknown*&
にのみバインドできます。右辺値にバインドできません。const 修飾された左辺値参照 ( など)は、右辺値にバインドできます。IUnknown* const&
ポインターや関数呼び出しを含まない、より単純なケースを検討する方が簡単です。
int i = 0;
double x = i; // (1) Well-formed
double const& y = i; // (2) Well-formed
double& z = i; // (3) Ill-formed
ここでi
は、タイプのオブジェクトですint
。を式で使用するi
と、左辺値になります。
(1)では、(型の) から(x
型の)オブジェクトを初期化します。型が一致しませんが、 からへの暗黙的な変換があるため、これは問題ありません。この変換の「結果」は、初期化に使用されるtypeの右辺値式(*)です。double
i
int
int
double
double
x
(2)では、 y
(型のdouble const&
) const 修飾された参照を から初期化しi
ます。ここでも型が一致しないため、暗黙的な変換を使用して を に変換int
しdouble
ます。この変換の「結果」は右辺値です。冒頭で述べたように、 const 修飾された参照はrvalueにバインドできるためy
、変換の「結果」にバインドされます。
(3)では、 からz
(型のdouble&
)非 const 参照を初期化しようとしますi
。タイプが一致しないため、変換が必要になります。変換の「結果」はrvalueであり、冒頭で述べたように、非 const 参照はrvalueにバインドできないため、ここでは変換を使用できません。
C++ には、右辺値式にバインドする const 左辺値参照を許可する特別な規則があります。その理由は、 「非 const 参照が一時オブジェクトにバインドできないのはなぜですか?」など、StackOverflow に関する他の質問から確認できます。
あなたの場合はこれとまったく同じです: 引数の型 ( IDXGIFactory*
) はパラメーターの型 (IUnknown*
またはそれへの参照) と同じではないため、引数をパラメーターの型に変換するには暗黙的な変換が必要です (この場合、派生クラスへのポインターから基底クラスへのポインターへの変換です)。ただし、この変換の「結果」は右辺値式であるため、非 const 参照にバインドできませんIUnknown*&
。
(*)それは本当に prvalue です。簡単にするために、この回答では C++98 式の分類法を使用しました。C++11 の値のカテゴリについては、この質問を参照してください。