这在clang 3.3中可以正常编译:
template <typename T>
struct M;
template <typename R, typename C, typename... A>
struct M <R (C::*)(A...)> { };
template <typename R, typename C, typename... A>
struct M <R (C::*)(A...) &> { };
但在gcc 4.8.1中失败:
[...] error: redefinition of ‘struct M <R (C::*)(A ...)>’
struct M <R (C::*)(A...) &> { };
^
[...] error: previous definition of ‘struct M <R (C::*)(A ...)>’
struct M <R (C::*)(A...)> { };
^
在不同的上下文中使用时,这会导致各种意外的编译器行为,例如崩溃或内部编译器错误。
我知道ref限定的成员函数在标准中被称为“ * this的右值引用”(N2439),并且受gcc 4.8.1支持。
这里的问题是将它们用作模板参数,其中gcc似乎无法区分ref限定类型和普通成员函数类型。
clang的std库实现似乎检测到此功能是否受支持
__has_feature(cxx_reference_qualified_functions)
那么,这是使用ref限定的函数标准还是语言扩展?
根据8.3.5 [dcl.fct]第6段(我在引用的文本中添加了一些突出显示的内容):
返回类型,parameter-type-list,ref-qualifier和cv-qualifier-seq(但不是默认参数(8.3.6)或异常规范(15.4))是函数type的一部分。
也就是说,ref限定符肯定是该类型的一部分。进一步根据8.4.1 [dcl.fct.def.general]第5段,您可以创建指向成员的指针,包括ref限定符:
cv-qualifier-seq或ref限定符(或两者)可以是非静态成员函数声明,非静态成员函数定义或仅指向成员函数的指针的一部分(8.3.5);见9.3.2。
对于使用ref-qualifier的成员函数的指针不能用作非类型模板参数,没有特别的限制。也就是说,我认为您尝试使用的部分专业化应该起作用。但是,在lang和gcc中,对ref限定符的支持是一个相当新的功能,即,可能不是所有的极端情况都已解决。我在上面用gcc(20130811)和clang(trunk 190769)的最新快照尝试了上述片段,并且都编译了代码。当然,此代码片段实际上并没有做任何事情,我也没有尝试滥用此功能。我猜您刚刚触发了一些编译器错误,并且我相信这两个项目都将赞赏根据其最新快照提供的错误报告。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句