C++ IUnknown指针引用

C++ IUnknown指针引用,c++,visual-c++,dxgi,visual-c++-2013,C++,Visual C++,Dxgi,Visual C++ 2013,为什么VisualStudio编译器对 void fn(int *&i) { ; } 及 但不是 void fn(IUnkown *&p) { ; } 它看起来像什么 IDXGIFactory *df = nullptr; // init df fn(df); 编译器错误为 3 IntelliSense:类型为“IUnknown*&”(非const-qualified)的引用不能用类型为“IDXGIFactory*”的值初始化c:\Users\Carl\D

为什么VisualStudio编译器对

void fn(int *&i) 
{
    ;
}

但不是

void fn(IUnkown *&p)
{
    ;
}
它看起来像什么

IDXGIFactory *df = nullptr;
// init df
fn(df);
编译器错误为

3 IntelliSense:类型为“IUnknown*&”(非const-qualified)的引用不能用类型为“IDXGIFactory*”的值初始化c:\Users\Carl\Documents\Visual Studio 2013\Projects\Project1\Project5\main.cpp 29 10 Project5


我在研究中发现的最接近事实是编译器一次只能进行一次类型转换,但这不可能是正确的,因为此时const&version应该停止进行类型和const转换;然而,实际上不会编译的是&version。

非常量左值引用(如
IUnknown*&
)只能绑定到左值;它不能绑定到右值。常量限定左值引用(如
IUnknown*const&
)可以绑定到右值

<> P>更容易考虑一个不涉及指针或函数调用的简单情况:

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)中,我们从
i
(类型
int
)初始化对象
x
(类型
double
)。类型不匹配,但这没有问题,因为存在从
int
double
的隐式转换。此转换的“结果”是一个类型为
double
的右值表达式(*),用于初始化
x

(2)中,我们从
i
初始化常量限定引用
y
(类型为
双常量&
)。同样,类型不匹配,因此隐式转换用于将
int
转换为
double
。此转换的“结果”为右值。如开头所述,常量限定引用可以绑定到右值,因此
y
绑定到转换的“结果”

(3)中,我们尝试从
i
初始化非常量引用
z
(类型为
double&
)。类型不匹配,因此需要进行转换。此处不能使用转换,因为转换的“结果”是一个右值,并且如开头所述,非常量引用不能绑定到右值

C++有特殊的规则允许常量左值引用绑定到右值表达式。你可以从StackOverflow的其他问题中找到原因,比如

您的情况与此完全相同:参数的类型(
IDXGIFactory*
)与参数的类型(
IUnknown*
或其引用)不同,因此需要隐式转换才能将参数转换为参数类型(在本例中,它是从指向派生类的指针到指向基类的指针的转换)。但是,此转换的“结果”是一个右值表达式,因此它无法绑定到非常量引用
IUnknown*&


(*)它实际上是一个prvalue;为了简单起见,我在回答中使用了C++98表达式分类法。有关C++11值类别的信息,请参阅。

转换的“结果”是一个右值,这是我缺少的。谢谢!
int i = 0;

double        x = i; // (1) Well-formed
double const& y = i; // (2) Well-formed
double&       z = i; // (3) Ill-formed