title: Why has this C++ code an ambiguous method call only on Microsoft compiler?
body: <p>I'm trying to compile a library on microsoft C++ compiler 14.1 (Visual Studio 2017) but I'm getting a strange error due to an ambiguous call to a class method.
  After some testing I isolated the following code snippet:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  struct Event
  {};
  
  template&lt;typename Derived&gt;
  struct State
  {
  public:
      template&lt;typename Fsm&gt;
      void onEvent(Fsm&amp; fsm, const Event&amp; event)
      {
          std::cout &lt;&lt; "State::onEvent\n";
      }
  
  };
  
  struct DerivedState
      : State&lt;DerivedState&gt;
  {
  public:
      using State::onEvent;
  
      template&lt;typename Fsm&gt;
      void onEvent(Fsm&amp; fsm, const Event&amp; event)
      {
          std::cout &lt;&lt; "DerivedState::onEvent\n";
      }
  
  };
  
  struct Context
  {};
  
  
  int main()
  {
      DerivedState ds;
      Context context;
      ds.onEvent(context, Event());
  }
  </code></pre>
  
  <p>I get the following output:</p>
  
  <p>1>c:\users\pmas\documents\visual studio </p>
  
  <pre><code>2017\projects\consoleapplication3\consoleapplication3\consoleapplication3.cpp(87): error C2668: 'DerivedState::onEvent': ambiguous call to overloaded function
  1&gt;c:\users\pmas\documents\visual studio 2017\projects\consoleapplication3\consoleapplication3\consoleapplication3.cpp(59): note: could be 'void DerivedState::onEvent&lt;Context&gt;(Fsm &amp;,const Event &amp;)'
  1&gt;        with
  1&gt;        [
  1&gt;            Fsm=Context
  1&gt;        ]
  1&gt;c:\users\pmas\documents\visual studio 2017\projects\consoleapplication3\consoleapplication3\consoleapplication3.cpp(45): note: or       'void State&lt;DerivedState&gt;::onEvent&lt;Context&gt;(Fsm &amp;,const Event &amp;)'
  1&gt;        with
  1&gt;        [
  1&gt;            Fsm=Context
  1&gt;        ]
  1&gt;c:\users\pmas\documents\visual studio 2017\projects\consoleapplication3\consoleapplication3\consoleapplication3.cpp(87): note: while trying to match the argument list '(Context, Event)'
  </code></pre>
  
  <p>The code looks to me perfectly legal and compiles fine on gcc, clang and icc (and behaves as expected, too).</p>
  
  <p>After some additional testing, I find out that the code compiles fine if I avoid the CRTP pattern in deriving <code>DerivedState</code>:</p>
  
  <pre><code>#include &lt;iostream&gt;
  
  struct Event
  {};
  
  struct State
  {
  public:
      template&lt;typename Fsm&gt;
      void onEvent(Fsm&amp; fsm, const Event&amp; event)
      {
          std::cout &lt;&lt; "State::onEvent\n";
      }
  
  };
  
  struct DerivedState
      : State
  {
  public:
      using State::onEvent;
  
      template&lt;typename Fsm&gt;
      void onEvent(Fsm&amp; fsm, const Event&amp; event)
      {
          std::cout &lt;&lt; "DerivedState::onEvent\n";
      }
  
  };
  
  struct Context
  {};
  
  
  int main()
  {
      DerivedState ds;
      Context context;
      ds.onEvent(context, Event());
  }
  </code></pre>
  
  <p>Can anybody explain this difference? Is microsoft compiler not conforming to the standard?</p>