重现问题的示例代码:
#include <iostream>
template< typename T, typename Func >
void action(Func T::* func)
{
T entry;
(entry.*func)();
}
struct A
{
void f()
{
std::cout << "A::f()" << std::endl;
}
};
int main()
{
action(&A::f);
return 0;
}
此代码使用VC ++ 2015成功编译,VC ++ 2015使用vc140工具集,但在VC ++ 2015项目中使用vc90(VC ++ 2008)工具集时无法编译。提供奇怪的诊断
cpptest.cpp(20): error C2664: 'action' : cannot convert parameter 1 from 'void (__thiscall A::* )(void)' to 'void (A::* )(void)'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
在推断Func的类型时,似乎编译器失去了__thiscall调用约定说明符。试图强行在代码的不同部分指定__thiscall但没有成功。将整个项目转换为vc14工具集不是一种方式,因为各种依赖关系并将其保持在VS 2008下是不太可能的方式。有什么想法迫使编译器理解这样的构造吗?
将代码更改为
template< typename T, typename Func >
void action(Func func)
....
并且调用action< A >( &A::f );
有效,但看起来有点难看 - 我希望编译器能够自动推导出两个模板参数(T和Func)的类型