ref-qualified成员函数作为模板参数?

iav*_*avr 9 c++ templates member-functions c++11 ref-qualifier

这在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...) &> { };
Run Code Online (Sandbox Code Playgroud)

但在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...)> { };
        ^
Run Code Online (Sandbox Code Playgroud)

在不同的上下文中使用时,会导致各种意外的编译器行为,如崩溃或内部编译器错误.

我理解ref-qualified成员函数在标准中称为"*this的右值引用"(N2439),并受gcc 4.8.1支持.

这里的问题是将它们用作模板参数,其中gcc似乎不区分ref-qualified和普通成员函数类型.

clang的std库实现似乎检测是否支持此功能

__has_feature(cxx_reference_qualified_functions)
Run Code Online (Sandbox Code Playgroud)

那么,这是使用ref-qualified函数标准还是语言扩展?

Die*_*ühl 3

根据 8.3.5 [dcl.fct] 第 6 段(我在引用的文本中添加了一些突出显示):

返回类型、参数类型列表、ref-qualifier和 cv-qualifier-seq是函数 type 的一部分,但默认参数 (8.3.6) 或异常规范 (15.4)除外。

也就是说,引用限定符肯定是类型的一部分。进一步根据 8.4.1 [dcl.fct.def.general] 第 5 段,您可以创建包含 ref 限定符的指向成员的指针:

cv-qualifier-seq 或ref-qualifier(或两者)可以是非静态成员函数声明、非静态成员函数定义或仅指向成员函数的指针的一部分(8.3.5);见 9.3.2。

没有具体限制指向带有 ref 限定符的成员函数的指针不能用作非类型模板参数。也就是说,我认为您尝试使用的部分专业化应该有效。然而,对 ref-qualifiers 的支持在 clang 和 gcc 中都是一个相当新的功能,也就是说,可能并没有解决所有的极端情况。我尝试使用 gcc (20130811) 和 clang (trunk 190769) 的最新快照进行上面的截图,并且都编译了代码。当然,这个片段并没有真正做任何事情,我也没有试图滥用这个功能。我猜您刚刚触发了一些编译器错误,并且我确信这两个项目都会欣赏针对其最新快照的错误报告。