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

标签 c++ templates template-argument-deduction

使用 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, "");

这背后的基本原理是,否则您将无法将 &D::f 的值分配给 void ( B::* )(void) 类型没有强制转换,即使 fB 的成员或比较 &D::f == &B::f

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

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

关于c++ - 为什么指针到成员函数的模板参数推导失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47201359/

相关文章:

c++ - 如何使用转换函数模板将 map 转换为 vector

c++ - 增加顶级 const 指针时发生了什么?

c++ - 有没有办法使用模板特化将 new 与 new [] 分开?

C++: boost::fusion::for_each 对于许多序列

templates - 文本模板中的线程安全映射

c++ - 为什么 C++ 无法推断模板化的非类型模板参数?

c++ - 如何在 C++ Gtest 中测试输入和输出重载运算符

c++ - 填充 unordered_set 太慢

c++ - 为什么大括号初始值设定项的自动和模板类型推导不同?

c++ - SFINAE 和重载函数的地址