Ссылка на неизвестный указатель

Почему компилятор Visual Studio доволен

void fn(int *&i)
{
;
}

а также

void fn(IUnknown *const &p)
{
;
}

но нет

void fn(IUnkown *&p)
{
;
}

где звонит это выглядит

IDXGIFactory *df = nullptr;
// init df
fn(df);

ошибка компилятора

3 IntelliSense: ссылка типа «IUnknown *&«(не соответствует const) не может быть инициализирован значением типа« IDXGIFactory * »c: \ Users \ Carl \ Documents \ Visual Studio 2013 \ Projects \ Project1 \ Project5 \ main.cpp 29 10 Project5

Самое близкое, что я нашел в исследованиях, это то, что компилятор будет выполнять только одно преобразование типов за раз, но это не может быть правильным, потому что тогда Const & версия должна прерваться от выполнения преобразования типа и const; Однако это & версия, которая на самом деле не будет компилироваться.

0

Решение

Неконстантная ссылка lvalue (например, IUnknown*&) может привязываться только к именующий; он не может связываться с 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 используется в выражении, это именующий.

В (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; Я использовал таксономию выражения C ++ 98 в этом ответе для простоты. Увидеть этот вопрос для получения информации о категориях значений C ++ 11.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]