【发布时间】:2020-07-30 08:28:51
【问题描述】:
我正在玩弄指向非静态方法的函数指针,并偶然发现了一些对我来说不太有意义的 GCC 消息。让我们看看一些代码:
#include<iostream>
struct X{ int print() const { std::cout << "hello"; return 0; } };
struct Y: public X{};
template<class T>
struct print_one
{
const T& t;
print_one(const T& _t): t(_t) {}
template<class Something>
void _call(Something (T::*fct)() const) const
{
std::cout << (t.*fct)() << '\n';
}
void do_print() const { _call(&T::print); }
};
int main()
{
X x;
Y y;
print_one<X>(x).do_print();
//print_one<Y>(y).do_print();
}
我已经准备好看到这个失败,因为我认为方法的返回值不会影响它的“ID”(编辑:它的签名)可以这么说。但是,这可以编译 (gcc-9 --std=c++17) 并且工作正常。
但是,如果我用Y 实例化print_one(取消main() 中的最后一行注释),事情就会向南:
test_ptr.cpp: In instantiation of 'void print_one<T>::do_print() const [with T = Y]':
test_ptr.cpp:28:28: required from here
test_ptr.cpp:19:27: error: no matching function for call to 'print_one<Y>::_call(int (X::*)() const) const'
19 | void do_print() const { _call(&T::print); }
| ^~~~~
test_ptr.cpp:14:8: note: candidate: 'template<class Something> void print_one<T>::_call(Something (T::*)() const) const [with Something = Something; T = Y]'
14 | void _call(Something (T::*fct)() const) const
| ^~~~~
test_ptr.cpp:14:8: note: template argument deduction/substitution failed:
test_ptr.cpp:19:27: note: mismatched types 'const Y' and 'const X'
19 | void do_print() const { _call(&T::print); }
| ^~~~~
特别是with Something = Something 对我来说似乎很奇怪。此外,如果我像这样明确地给出模板实例化,整个事情都会起作用:_call<int>(&T::print)。
所以,问题是:为什么 GCC 可以推导出模板参数 Something,尽管它不是 print 方法签名的一部分,为什么当遇到派生自定义实际方法?
【问题讨论】:
标签: c++ c++11 gcc template-argument-deduction