我想要一个这样的函数:
MyClass
参数是(在文字中,因为C / C ++类型语法是精神上的):
MyClass
。T
成员函数的const指针,它接受一个unsigned int并返回C
。这种工作,但是如果我用l值引用作为第一个参数调用它,我会收到如下错误:
忽略候选模板:推导出参数' C'的冲突类型。 (' MyClass&' vs.' MyClass')
据我了解,它是从第一个和第二个参数中推导出typename
,但会产生不同的推论并且会混淆。
根据this answer,你可以只对第一个参数进行推论,并以某种方式在第二个参数上使用T
关键字。但是,当我希望它推导出参数(C
)中的一种类型而不是其他类型(C
)时,我无法解决语法问题。
This answer也很有用,但是他们只是根本不使用bash-3.2$ ifconfig en1
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 24:a0:74:ef:c2:0a
inet6 fe80::1421:2877:9b9f:8b7e%en1 prefixlen 64 secured scopeid 0x5
inet 192.168.0.56 netmask 0xffffff00 broadcast 192.168.0.255
nd6 options=201<PERFORMNUD,DAD>
media: autoselect
status: active
bash-3.2$ ping -S 192.168.0.56 www.google.com
PING www.google.com (172.217.166.68) from 192.168.0.56: 56 data bytes
64 bytes from 172.217.166.68: icmp_seq=0 ttl=55 time=26.458 ms
64 bytes from 172.217.166.68: icmp_seq=1 ttl=55 time=21.927 ms
bASH-3.2$ scapy
WARNING: Cannot read wireshark manuf database
WARNING: Crypto-related methods disabled for IPsec, Dot11 and TLS
layers (needs python-cryptography v1.7+).
WARNING: No route found for IPv6 destination :: (no default route?)
INFO: Can't import python-cryptography v1.7+. Disabled WEP
decryption/encryption.
INFO: Can't import python-cryptography v1.7+. Disabled IPsec
encryption/authentication.
WARNING: IPython not available. Using standard Python shell instead.
AutoCompletion, History are disabled.
aSPY//YASa
apyyyyCY//////////YCa |
sY//////YSpcs scpCY//Pp | Welcome to Scapy
ayp ayyyyyyySCP//Pp syY//C | Version 2.4.0rc4
AYAsAYYYYYYYY///Ps cY//S |
pCCCCY//p cSSps y//Y | https://github.com/secdev/scapy
SPPPP///a pP///AC//Y |
A//A cyP////C | Have fun!
p///Ac sC///a |
P////YCpc A//A | To craft a packet, you have to be a
scccccp///pSP///p p//Y | packet, and learn how to swim in
sY/////////y caa S//P | the wires and in the waves.
cayCyayP//Ya pY/Ya | -- Jean-Claude Van Damme
sY/PsY////YCc aC//Yp |
sc sccaCY//PCypaapyCP//YSs
spCPY//////YPSps
ccaacs
>>> sr(IP(dst='www.google.com')/ICMP())
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Library/Python/2.7/site-packages/scapy-2.4.0rc4-
py2.7.egg/scapy/sendrecv.py", line 364, in sr
s = conf.L3socket(promisc=promisc, filter=filter, iface=iface,
nofilter=nofilter)
File "/Library/Python/2.7/site-packages/scapy-2.4.0rc4-
py2.7.egg/scapy/arch/bpf/supersocket.py", line 57, in __init__
(self.ins, self.dev_bpf) = get_dev_bpf()
File "/Library/Python/2.7/site-packages/scapy-2.4.0rc4-
py2.7.egg/scapy/arch/bpf/core.py", line 98, in get_dev_bpf
raise Scapy_Exception("No /dev/bpf handle is available !")
Scapy_Exception: No /dev/bpf handle is available
的引用来解决它,在这种情况下同样有效,但不在我的。< / p>
这可能吗?
答案 0 :(得分:7)
对于第一个参数,左值C
将被推断为左值引用类型(即您的案例的MyClass &
),这是forwarding reference的预期行为;您可以在第二个参数中使用C
时通过std::remove_reference删除引用,例如
template<typename C, typename T>
void foo(C &&aclass, T (std::remove_reference_t<C>::*const memberFunc)(unsigned)) {
}
正如@Quentin所指出的那样,使用std::remove_reference
也会引入non-deduced context,这会阻止从第二个参数推断C
。
答案 1 :(得分:0)
实际上我发现有一个通用引用重载将它转发到l值引用版本。虽然不是特别优雅;我觉得应该有更好的方法。
template<typename C, typename T>
void foo(C &aclass, T (C::*const memberFunc)(unsigned)) {
// Code goes here.
}
template<typename C, typename T>
void foo(C &&aclass, T (C::*const memberFunc)(unsigned)) {
foo(aclass, memberFunc);
}