首页 > 解决方案 > C++ 函数指针传递在 vs2008 中编译,但在 vs2017 中不编译

问题描述

有人可以告诉我为什么这个 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)'

它来自我试图升级到 vs2017 的一些 20 多年的旧代码。

我错过了什么?是否有需要设置或清除的编译器属性是 vs2017 的新属性(或至少比 vs2008 更新)?或者这只是一些不再编译的非常古老的代码?这有点超出我的想象。

标签: c++mfc

解决方案


(假设您正在谈论 MFC CArray,其中第二个模板参数ARG_TYPE成为CArray<>::Add成员函数的参数类型)。

您传递给的参数Add- &VStatusSrvr::CreateLineSegTotalResp- 不是左值。并且参数Add具有类型void (VStatusSrvr::*&)(),它是一个非常量左值引用。在标准 C++ 中,您不能将非常量左值引用绑定到非左值。

旧版本的 Visual Studio 允许将此非标准行为作为扩展,默认启用。在 Visual Studio 2017 中,此扩展仍然存在,但默认情况下已禁用。因此错误。

如果您使用 const 引用(即对 const 的引用)作为 的第二个模板参数CArray,它应该可以工作

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

无论如何,您为什么还要通过引用传递成员函数指针?为什么不只是通过价值传递它而忘记整个问题呢?

CArray< void (VStatusSrvr::*)(), void (VStatusSrvr::*)() > m_fnCreateStsRespArr;

推荐阅读