問題を再現するサンプル コード:
#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;
}
このコードは、MS VC++2008 を使用すると正常にコンパイルされ、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)の型を自動的に推測できることを期待しています