Неконстантная ссылка lvalue (например, IUnknown*&
) может быть связана только с lvalue; он не может быть привязан к rvalue. Константная ссылка lvalue (например, IUnknown* const&
) может связываться с rvalue.
Легче рассмотреть более простой случай, не связанный с указателями или вызовами функций:
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
, это lvalue.
В (1) мы инициализируем объект x
(типа double
) из i
(типа int
). Тип не совпадает, но это нормально, потому что происходит неявное преобразование из int
в double
. «Результатом» этого преобразования является выражение rvalue(*) типа double
, которое используется для инициализации x
.
В (2) мы инициализируем константную ссылку y
(типа double const&
) из i
. Опять же, типы не совпадают, поэтому для преобразования int
в double
используется неявное преобразование. «Результатом» этого преобразования является rvalue. Как отмечалось в начале, ссылка с уточнением const может связываться с rvalue, поэтому y
связывается с "результатом" преобразования.
В (3) мы пытаемся инициализировать неконстантную ссылку z
(типа double&
) из i
. Типы не совпадают, поэтому потребуется преобразование. Преобразование здесь использовать нельзя, так как «результатом» преобразования является rvalue, а, как отмечалось в начале, неконстантная ссылка не может быть связана с rvalue. .
C++ имеет специальные правила, позволяющие привязывать ссылки const lvalue к выражениям rvalue. Вы можете узнать почему из других вопросов здесь, в StackOverflow, например "Почему неконстантная ссылка не может быть привязана к временному объекту?"
Ваш случай точно такой же, как и этот: тип вашего аргумента (IDXGIFactory*
) не совпадает с типом параметра (IUnknown*
или ссылка на него), поэтому требуется неявное преобразование для преобразования аргумента в тип параметра (в данном случае это преобразование указателя на производный класс в указатель на базовый класс). Однако «результатом» этого преобразования является выражение rvalue, поэтому оно не может привязываться к неконстантной ссылке IUnknown*&
.
(*)Это действительно prvalue; Я использовал таксономию выражений С++ 98 в этом ответе для простоты. См. этот вопрос для получения информации о значении C++11. категории.
person
James McNellis
schedule
23.10.2013