繁体   English   中英

为什么模板参数推导失败指针到成员函数?

[英]Why is template argument deduction failing for pointer-to-member-function?

用g ++ 5.4,这个

struct B {
    void f() {}
}; 

struct D : public B {
    void g() {}
};

template <class T>
void foo(void (T::*)(), void (T::*)())
{}

int main()
{
    foo(&D::f, &D::g);
}

由于“推断出参数'T'('B'和'D')的冲突类型而失败”。 为什么不将T推导为D,完全匹配?

&D::f的类型将为void ( B::* )(void)

static_assert(::std::is_same<void ( B::* )(void), decltype(&D::f)>::value, "");
static_assert(::std::is_same<void ( D::* )(void), decltype(&D::f)>::value, ""); // error
static_assert(::std::is_same<void ( D::* )(void), decltype(&D::g)>::value, "");

这背后的基本原理是,即使fB的成员或比较,否则你将无法在没有强制转换的情况下将&D::f的值赋给void ( B::* )(void)类型的变量。 &D::f == &B::f

作为解决方法,您可以执行static_cast:

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

除了VTT的出色演示 我相信,有问题的标准文本是在[expr.unary.op] / 3 ,强调我的:

一元&运算符的结果是指向其操作数的指针。 操作数应为左值或限定ID。 如果操作数是一个qualified-id,命名一个类型为T的某个类C的非静态或变体成员m,则结果类型为“指向类型为C的C类成员的指针”,并且是一个指定C ::的prvalue米

您使用的限定ID是D::f ,但它命名为B的成员函数(如果需要,我可以调出查找规则)。 所以上段中的类CB 因此该类型解析为void ( B::* )(void)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM