标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?

What does the standard say about this pointer-to-member-function type template parameter? Is my code wrong, or is MSVS 16.6 buggy?

本文关键字:代码 我的 有问题 MSVS 还是 说明 成员 函数 类型 何说明 标准      更新时间:2023-10-16

以下是一些适用于GCC,Clang和MSVS的代码(至少是编译器资源管理器上当前可用的版本(:

template <typename T, auto T::* MemberPtr>
struct Foo
{
Foo(const T& e) : _e(e) {}
void operator()() const
{
(_e.*MemberPtr)();
}
private:
const T& _e;
};
struct Bar
{
void baz() const {}
auto bind()
{
using BindingType = Foo<Bar, &Bar::baz>;
return BindingType(*this);
}
};
int main()
{
Bar i;
i.bind();
}

但是,从 v16.6.1 开始,MSVS 拒绝它:

Severity  Code   Description                                                                      Line
Error     C2973  'Foo': invalid template argument 'int'                                           23
Error     E2886  cannot deduce 'auto' template parameter type "auto T::*" from "void (Bar::*)()"  21
Error     C2440  'specialization': cannot convert from 'overloaded-function' to 'auto Bar::* '    22
Error     C3535  cannot deduce type for 'auto Bar::* ' from 'int'                                 23
Error     C2440  'specialization': cannot convert from 'int' to 'int Bar::* '                     23

代码可以通过去掉MemberPtrT::*限定符来"修复"该版本中;因此:

template <typename T, auto MemberPtr>

标准对此有何规定?VS v16.6.1 是引入了新的回归,还是现在诊断总是微妙地破坏的代码?

参数/参数组合按原样有效

[温度参数]

4 非类型模板参数应具有以下其中一项 (可选符合 CV 标准(类型:

  • 包含占位符类型的类型。

[temp.arg.nontype]

1 如果模板参数的类型包含占位符 类型,推导的参数类型由 按占位符类型推断的模板参数。如果推导 模板参数声明不允许使用参数类型 ([temp.param](,程序格式不正确。

现在,auto T::*是包含占位符类型的类型。并且 placholder 类型推导在表单中的变量声明中工作得很好

auto Bar::* foo = &Bar::baz;

所以VS v16.6.1没有拒绝这种非类型模板参数的业务。

相关文章: