我在调用类成员函数时遇到了一个奇怪的问题。 我构建了一个使用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地址而不是字符串变量。如果未设置“硬编码”,则结果是无法使用任何成员函数。但这仅涉及成员函数。 construtor本身运行正常,最后一个参数为变量。
如果这不够奇怪,如果我只是为配置和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 ++正在尝试做什么(错误地)在这里做什么?
答案 0 :(得分:2)
您已发现Most Vexing Parse。只需将单个参数提取到构造函数(其自身构造函数采用四个参数的那个)输出到一个单独的变量中,然后传入该变量 - 应该修复它。
答案 1 :(得分:1)
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
构造函数调用看起来像是在声明一个命名函数参数。如果你将一个参数包装在括号中,问题就会解决。