Передача указателя функции C ++ компилируется в vs2008, но не в vs2017 - PullRequest
0 голосов
/ 03 июля 2018

Может кто-нибудь сказать, почему этот код C ++ успешно компилируется в Visual Studio 2008, но выдает ошибку в Visual Studio 2017?

класс VStatusSrvr

// array of status response functions created
CArray< void (VStatusSrvr::*)(), void (VStatusSrvr::*&)() > m_fnCreateStsRespArr;


// function call
void VStatusSrvr::CreateLineSegTotalResp()
{
}


// later adding function to array of response functions
m_fnCreateStsRespArr.Add( &VStatusSrvr::CreateLineSegTotalResp);

Ошибка C2664 «INT_PTR CArray :: Add (ARG_TYPE)»: невозможно преобразовать аргумент 1 из «void (__thiscall VStatusSrvr :: *) (void)» в «void (__thiscall VStatusSrvr :: * &) (void)»

Это код от 20+ лет, который я пытаюсь обновить до vs2017.

Что мне не хватает? Есть ли свойство компилятора, которое нужно установить или очистить, что является новым для vs2017 (или, по крайней мере, более новым, чем в vs2008)? Или это просто какой-то очень старый код, который больше не компилируется? Это немного за мной.

1 Ответ

0 голосов
/ 03 июля 2018

(при условии, что вы говорите о MFC CArray, где второй параметр шаблона ARG_TYPE становится типом параметра для CArray<>::Add функции-члена).

Аргумент, который вы передаете Add - &VStatusSrvr::CreateLineSegTotalResp - не является lvalue. И параметр Add имеет тип void (VStatusSrvr::*&)(), который является неконстантной ссылкой на lvalue. В стандартном C ++ нельзя связывать неконстантные ссылки на lvalue с ненулевыми значениями.

В старых версиях Visual Studio это нестандартное поведение допускалось как расширение, включенное по умолчанию. В Visual Studio 2017 это расширение все еще существует, но по умолчанию оно отключено. Отсюда и ошибка.

Если в качестве второго аргумента шаблона для CArray используется константная ссылка (т. Е. Ссылка на const), она должна работать

CArray< void (VStatusSrvr::*)(), void (VStatusSrvr::*const &)() > m_fnCreateStsRespArr;
...
m_fnCreateStsRespArr.Add( &VStatusSrvr::CreateLineSegTotalResp);

В любом случае, почему вы даже хотите передать указатель на функцию-член по ссылке? Почему бы просто не передать его по значению и не забыть обо всей этой проблеме?

CArray< void (VStatusSrvr::*)(), void (VStatusSrvr::*)() > m_fnCreateStsRespArr;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...