这个指向成员转换的指​​针有啥问题?

Posted

技术标签:

【中文标题】这个指向成员转换的指​​针有啥问题?【英文标题】:what is wrong with this pointer to member conversion?这个指向成员转换的指​​针有什么问题? 【发布时间】:2013-12-04 13:55:10 【问题描述】:

这段代码有什么问题?由于这个答案,我认为我可以转换:

Is it safe to "upcast" a method pointer and use it with base class pointer?

struct B

  void f()
;

struct D : B

  virtual ~D()
;

template <typename FP, FP fp>
void g()



int main()

  g<void (D::*)(), &B::f>();
  return 0;

错误:

t.cpp:18:27: error: could not convert template argument '&B::f' to 'void (D::*)()'
   g<void (D::*)(), &B::f>();

这也不起作用:

g<void (D::*)(), static_cast<void (D::*)()>(&B::f)>();

【问题讨论】:

@PeteBecker 我也尝试过强制转换,没有运气。 【参考方案1】:

标准不允许这样做(C++11,[temp.arg.nontype]§5):

对每个用作非类型模板参数的表达式执行以下转换。如果非类型模板参数不能转换为相应的模板参数 那么程序是不正确的。

...

对于一个非类型的template-parameter类型的成员函数指针,如果template-argumentstd::nullptr_t类型,则空成员指针转换( 4.11) 适用; 否则,不适用任何转化。如果模板参数表示一组重载的成员函数,则从集合中选择匹配的成员函数 (13.4)。

(强调我的)

也不允许强制转换,因为 [temp.arg.nontype]§1:

非类型、非模板的模板参数应为以下之一:

...

指向成员的指针,如 5.3.1 中所述。

其中 5.3.1§4 内容如下:

只有在使用显式 &amp; 并且其操作数是未括在括号中的 qualified-id 时,才会形成指向成员的指针。

这结合起来表示不允许将强制转换表达式作为非类型模板参数。

因此,虽然这样的转换在运行时是可能的,但似乎没有办法将它们用作模板参数。

【讨论】:

为什么演员表也不起作用?如何解决问题? @user1095108 我添加了更多信息。我认为不存在解决方法。 不允许这样做有什么技术原因吗?在我看来,实例化模板所需的一切(即 B::f 的位置)都可以在编译时确定。

以上是关于这个指向成员转换的指​​针有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

错误:'指向成员的指针对托管类无效'

指向成员的指针对托管类无效

将指向成员的 C++ 指针转换为 C#

向下转换指向成员函数的指针

尝试使用指向成员函数的指针时出现强制转换问题

Swig:将成员变量(指向值的指针)转换为 python 列表