调用成员类时出现非类类型错误

Non-class type error on invocation of a member class

本文关键字:类型 错误 成员类 调用      更新时间:2023-10-16

我在调用类成员函数时遇到了一个奇怪的问题。我构建了一个类来处理使用Netlink的IPsec连接。此类将配置对象作为构造函数参数,该参数再次使用自定义IPAddress对象进行构造。地址对象由一个包含实际IP地址的字符串构成。然后我调用IPsec类的一个成员函数,它添加了一个SA(也使用配置类)。

我无法解释的是调用上述函数添加SA:时的编译器错误

std::string svsrc, svdst, spsrc, spdst, spdev;
svsrc="10.0.0.1";
svdst="10.0.0.2";
spsrc="10.0.0.3";
spdst="10.0.0.4";  
NetlinkIPsecManager ipsmgr(IPsecConfig(IPAddress(svsrc),IPAddress(svdst),IPAddress(spsrc),IPAddress(spdst)));
ipsmgr.addSA(SAConfig(keyfield,"aes",1234));

这会产生以下错误消息:

request for member 'addSA' in 'ipsmgr', which is of non-class type 'NetlinkIPsecManager(IPsecConfig (*)(IPAddress, IPAddress, IPAddress, IPAddress))'

我真的无法解释这个错误,但真正奇怪的部分如下,因为这实际上是有效的:

std::string svsrc, svdst, spsrc, spdst, spdev;
svsrc="10.0.0.1";
svdst="10.0.0.2";
spsrc="10.0.0.3";
spdst="10.0.0.4";    
NetlinkIPsecManager ipsmgr(IPsecConfig(IPAddress(svsrc),IPAddress(svdst),IPAddress(spsrc),IPAddress("10.0.0.4")));
ipsmgr.addSA(SAConfig(keyfield,"aes",1234));

唯一的区别是构造函数最后一个参数中的"硬编码"IP地址,而不是字符串变量如果不设置为"硬编码",结果是无法使用任何成员函数。不过,这只涉及成员的职能。最后一个自变量作为变量时,解释器本身运行良好。

如果这还不够奇怪的话,如果我只是为我的配置和IP地址成员类实例化命名对象,而不是在构造函数调用中使用无名称对象,那么它也适用于字符串对象。

svsrc="10.0.0.1";
svdst="10.0.0.2";
spsrc="10.0.0.3";
spdst="10.0.0.4";
IPAddress vsrc(svsrc);
IPAddress vdst(svdst);
IPAddress psrc(spsrc);
IPAddress pdst(spdst);
IPsecConfig ipc(vsrc,vdst,psrc,pdst);
NetlinkIPsecManager ipsmgr(ipc);
ipsmgr.addSA(SAConfig(keyfield,"aes",1234));

所以,最后一个例子也运行得很好。由于这对我来说是一个可行的解决方案,这不是什么大问题,但我只想知道是否有人对这里发生的事情有一个的想法。我觉得这种行为很奇怪,我很好奇可能是什么问题。那么,有人知道C++在这里试图(错误地)做什么吗?

您已经发现了Most Vexing Parse。只需将构造函数的单个参数(其自己的构造函数获取四个参数的构造函数)提取到一个单独的变量中,然后将其传递进去——这应该会修复它

ipsmgr已声明为返回NetlinkIPsecManager的函数,并将指向返回IPsecConfig并具有4个IPAddress参数的函数的指针作为参数。

NetlinkIPsecManager ipsmgr(IPsecConfig(IPAddress(svsrc),IPAddress(svdst),IPAddress(spsrc),IPAddress(spdst)));
^return             ^name  ^return     ^param1   ^name  ^param2   ^name  ^param3   ^name  ^param4   ^name

构造函数调用看起来像是在声明一个命名函数参数。如果你把其中一个参数括在括号里,问题就会解决。