私は、Microsoft C++コンパイラ14.1(Visual Studio 2017)でライブラリをコンパイルしようとしていますが、クラスメソッドへのあいまいな呼び出しのために奇妙なエラーが発生しています。なぜこのC++コードは、Microsoftコンパイラでのみあいまいなメソッド呼び出しですか?
1> C:\ Users \ユーザーのPMAのドキュメントは、Visual Studioを\ \
2017\projects\consoleapplication3\consoleapplication3\consoleapplication3.cpp(87): error C2668: 'DerivedState::onEvent': ambiguous call to overloaded function
1>c:\users\pmas\documents\visual studio 2017\projects\consoleapplication3\consoleapplication3\consoleapplication3.cpp(59): note: could be 'void DerivedState::onEvent<Context>(Fsm &,const Event &)'
1> with
1> [
1> Fsm=Context
1> ]
1>c:\users\pmas\documents\visual studio 2017\projects\consoleapplication3\consoleapplication3\consoleapplication3.cpp(45): note: or 'void State<DerivedState>::onEvent<Context>(Fsm &,const Event &)'
1> with
1> [
1> Fsm=Context
1> ]
1>c:\users\pmas\documents\visual studio 2017\projects\consoleapplication3\consoleapplication3\consoleapplication3.cpp(87): note: while trying to match the argument list '(Context, Event)'
コード、私は次の出力を得る
#include <iostream>
struct Event
{};
template<typename Derived>
struct State
{
public:
template<typename Fsm>
void onEvent(Fsm& fsm, const Event& event)
{
std::cout << "State::onEvent\n";
}
};
struct DerivedState
: State<DerivedState>
{
public:
using State::onEvent;
template<typename Fsm>
void onEvent(Fsm& fsm, const Event& event)
{
std::cout << "DerivedState::onEvent\n";
}
};
struct Context
{};
int main()
{
DerivedState ds;
Context context;
ds.onEvent(context, Event());
}
: は、いくつかのテストの後、私は次のコードスニペットを分離しました私には完全に合法的に見え、gcc、clang、icc(そして期待どおりに動作します)でうまくコンパイルされます。いくつかの追加のテストの後
、私はDerivedState
を導出する際にCRTPパターンを避ける場合は、コードが正常にコンパイルされることを見つける:
#include <iostream>
struct Event
{};
struct State
{
public:
template<typename Fsm>
void onEvent(Fsm& fsm, const Event& event)
{
std::cout << "State::onEvent\n";
}
};
struct DerivedState
: State
{
public:
using State::onEvent;
template<typename Fsm>
void onEvent(Fsm& fsm, const Event& event)
{
std::cout << "DerivedState::onEvent\n";
}
};
struct Context
{};
int main()
{
DerivedState ds;
Context context;
ds.onEvent(context, Event());
}
誰がこの違いを説明できますか? Microsoftコンパイラは標準に準拠していませんか?宣言を使用cppreference documentation(強調鉱山)によれば