title: g++ std::variant seems can't support user class with std::atomic/std::mutex variable member (with detail/code)
body: <p>If I have a class with std::atomic_bool or std::mutex member for example, and if I put this class inside std::variant, my g++ will complain with &quot;no matching function for call to std::variant&lt;....&gt;&quot;. Now I have to declare my std::mutex member to be static.</p>
  <p>g++ (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5) Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p>
  <p>Actual code</p>
  <pre><code>#include &lt;iostream&gt;
  #include &lt;variant&gt;
  #include &lt;mutex&gt;
  
  enum class enFixEngineRunMode {
      eFixModeStreet      // Fix connection side as initiator/client
      ,eFixModeStreetStandAlone       // Fix connection side as initiator/client
      ,eFixModeStreetAccpt    // Fix connection side as acceptor/server
      ,eFixModeStreetAccptStandAlone  // Fix connection side as acceptor/server
      ,eFixModeClient     // Fix connection side as acceptor/client
      ,eFixModeClientStandAlone       // Fix connection side as acceptor/client
      ,eFixModeClientInit // Fix connection side as initiator/server
      ,eFixModeClientInitStandAlone   // Fix connection side as initiator/server
      ,eFixModeInvalid
  };
  
  struct FOO {
      FOO(int any) { }
      void operator()() const {
          std::cout &lt;&lt; &quot;FOO2&quot; &lt;&lt; std::endl;
      }
  };
  
  template &lt;enum enFixEngineRunMode&gt;
  struct BAR {
      BAR(double any) { }
      void operator()() const {
          std::cout &lt;&lt; &quot;BAR2&quot; &lt;&lt; std::endl;
      }
  
      std::mutex  m_metux;
  };
  
  template&lt;&gt;
  struct BAR&lt;enFixEngineRunMode::eFixModeStreetStandAlone&gt; {
      BAR(double any) { }
      void operator()() const {
          std::cout &lt;&lt; &quot;eFixModeStreetStandAlone&quot; &lt;&lt; std::endl;
      }
  };
  
  using EngineImpl = std::variant&lt;BAR&lt;enFixEngineRunMode::eFixModeStreet&gt;
                                  , BAR&lt;enFixEngineRunMode::eFixModeStreetStandAlone&gt;
                                  , BAR&lt;enFixEngineRunMode::eFixModeStreetAccpt&gt;
                                  , BAR&lt;enFixEngineRunMode::eFixModeStreetAccptStandAlone&gt;
                                  , BAR&lt;enFixEngineRunMode::eFixModeClient&gt;
                                  , BAR&lt;enFixEngineRunMode::eFixModeClientStandAlone&gt;
                                  , BAR&lt;enFixEngineRunMode::eFixModeClientInit&gt;
                                  , BAR&lt;enFixEngineRunMode::eFixModeClientInitStandAlone&gt;
                                  , BAR&lt;enFixEngineRunMode::eFixModeInvalid&gt;&gt;;
  
  struct Engine {
      Engine() : m_engine([&amp;] {
          int i = 2;
          if (1 == i)
              return EngineImpl(BAR&lt;enFixEngineRunMode::eFixModeStreetStandAlone&gt;(0.0));
          else return EngineImpl(BAR&lt;enFixEngineRunMode::eFixModeStreet&gt;(0.0));
      }()) {}
  
      void operator()() const {
          std::visit([](auto const&amp; e){ e(); }, m_engine);
      }
      EngineImpl  m_engine;
  };
  
  int main(int argc, const char *argv[], char** env)
  {
      Engine e;
      e();
      return 0;
  }
  
  </code></pre>
  <p>compilation error:</p>
  <pre><code>variantMain2.cpp:57:70: error: no matching function for call to ‘std::variant&lt;BAR&lt;(enFixEngineRunMode)0&gt;, BAR&lt;(enFixEngineRunMode)1&gt;, BAR&lt;(enFixEngineRunMode)2&gt;, BAR&lt;(enFixEngineRunMode)3&gt;, BAR&lt;(enFixEngineRunMode)4&gt;, BAR&lt;(enFixEngineRunMode)5&gt;, BAR&lt;(enFixEngineRunMode)6&gt;, BAR&lt;(enFixEngineRunMode)7&gt;, BAR&lt;(enFixEngineRunMode)8&gt; &gt;::variant(BAR&lt;(enFixEngineRunMode)0&gt;)’
     else return EngineImpl(BAR&lt;enFixEngineRunMode::eFixModeStreet&gt;(0.0));
                                                                        ^
  In file included from variantMain2.cpp:2:0:
  /opt/rh/devtoolset-7/root/usr/include/c++/7/variant:986:2: note: candidate: template&lt;long unsigned int _Np, class _Up, class ... _Args, class&gt; constexpr std::variant&lt;_Types&gt;::variant(std::in_place_index_t&lt;_Np&gt;, std::initializer_list&lt;_Up&gt;, _Args&amp;&amp; ...)
    variant(in_place_index_t&lt;_Np&gt;, initializer_list&lt;_Up&gt; __il,
    ^~~~~~~
  /opt/rh/devtoolset-7/root/usr/include/c++/7/variant:986:2: note:   template argument deduction/substitution failed:
  variantMain2.cpp:57:70: note:   ‘BAR&lt;(enFixEngineRunMode)0&gt;’ is not derived from ‘std::in_place_index_t&lt;_Idx&gt;’
     else return EngineImpl(BAR&lt;enFixEngineRunMode::eFixModeStreet&gt;(0.0));
                                                                        ^
  In file included from variantMain2.cpp:2:0:
  /opt/rh/devtoolset-7/root/usr/include/c++/7/variant:977:2: note: candidate: template&lt;long unsigned int _Np, class ... _Args, class&gt; constexpr std::variant&lt;_Types&gt;::variant(std::in_place_index_t&lt;_Np&gt;, _Args&amp;&amp; ...)
    variant(in_place_index_t&lt;_Np&gt;, _Args&amp;&amp;... __args)
  
  </code></pre>