非 const 左值引用(如IUnknown*&)只能绑定到左值;它不能绑定到rvalue。一个 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(类型)对象。类型不匹配,但这没关系,因为存在从to的隐式转换。此转换的“结果”是一个类型为 的右值表达式(*),用于初始化。doubleiintintdoubledoublex
在(2)中,我们从 初始化 const 限定引用y(类型为double const&)i。同样,类型不匹配,因此使用隐式转换将 to 转换int为double。这种转换的“结果”是一个rvalue。如开头所述,一个 const 限定的引用可以绑定到一个rvalue,因此y绑定到转换的“结果”。
在(3)中,我们尝试从 初始化非常量引用z(类型为double&)i。类型不匹配,因此需要进行转换。此处不能使用转换,因为转换的“结果”是rvalue,并且如开头所述,非常量引用不能绑定到rvalue。
C++ 有特殊规则允许 const 左值引用绑定到右值表达式。您可以从 StackOverflow 上的其他问题中找出原因,例如“为什么非常量引用不能绑定到临时对象?”
您的情况与此情况完全相同:您的参数(IDXGIFactory*)的类型与参数的类型(IUnknown*或对其的引用)不同,因此需要隐式转换才能将参数转换为参数类型(在在这种情况下,它是从指向派生类的指针到指向基类的指针的转换)。然而,这种转换的“结果”是一个右值表达式,因此它不能绑定到非常量引用IUnknown*&。
(*)这真的是一个prvalue;为简单起见,我在此答案中使用了 C++98 表达式分类法。有关 C++11 值类别的信息,请参阅此问题。