非 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的隐式转换。此转换的“结果”是一个类型为 的右值表达式(*),用于初始化。double
i
int
int
double
double
x
在(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 值类别的信息,请参阅此问题。