title: Compile time configurable callback
body: <p>I'm trying to implement compile-time configurable callback for sync/async call behaviour.</p>
  
  <p>Here is the first approach to do that: </p>
  
  <pre><code>//emit type's
  enum EEmitType
  {
     SYNC,
     ASYNC,
  };
  
  //general 
  template&lt;EEmitType et, typename... Args&gt;
  class callback_impl;
  
  //implementation
  template&lt;EEmitType et, typename R, typename... Args&gt;
  class callback_impl&lt;et, R(Args...)&gt;
  { /*todo*/ };
  
  //................................................................
  
  //convert enum value to type or SFINAE
  template &lt;EEmitType et&gt;
  using callback_emit_type = std::integral_constant&lt;EEmitType, et&gt;;
  
  //(for default SYNC)
  template &lt;typename T&gt;
  struct is_emit_type : std::false_type {};
  
  //(for any other implementation)
  template &lt;EEmitType et&gt;
  struct is_emit_type&lt;callback_emit_type&lt;et&gt;&gt; : std::true_type {};
  
  //................................................................
  
  //metafunction
  template &lt;typename T&gt;
  using is_emit_type_t = typename is_emit_type&lt;T&gt;::type;
  
  //................................................................
  
  //for decl. like: callback&lt;void()&gt;
  template &lt;typename _unused, typename... Args&gt;
  struct construct_callback_impl
  {
      //alias on implementation
      using type = callback_impl&lt;SYNC, Args...&gt;;
  };
  
  //for decl. like: callback&lt;callback_emit_type&lt;ASYNC&gt;, void()&gt;
  template &lt;typename EEmitType, typename... Args&gt;
  struct construct_callback_impl&lt;typename 
  std::enable_if&lt;is_emit_type_t&lt;EEmitType&gt;::value&gt;::type, EEmitType, Args...&gt;
  {
      //alias on implementation
      using type = callback_impl&lt;EEmitType::value, Args...&gt;;
  };
  
  //................................................................
  
  //user alias
  template &lt;typename... Args&gt;
  using callback = typename construct_callback_impl&lt;Args...&gt;::type;
  </code></pre>
  
  <p>Now USING:</p>
  
  <pre><code>callback&lt;int(int)&gt; ff_s; //&lt;--  uses undefined class 'callback_impl&lt;SYNC&gt;'
  callback&lt;callback_emit_type&lt;ASYNC&gt;, int(int)&gt; ff_a; //&lt;--OK
  </code></pre>
  
  <p>Of course because first args is eating, and for success compilation it should be write down like: </p>
  
  <pre><code> callback&lt;int(int), int(int)&gt; ff_s 
  </code></pre>
  
  <p>But of course it's not unacceptable.
  OK, then I try extract EEmitType from Args...</p>
  
  <pre><code>//for decl. like: callback&lt;void()&gt;
  template &lt;typename... Args&gt;
  struct construct_callback_impl
  {
     //alias on implementation
     using type = int; //temporary stub
  };
  
  //for decl. like: callback&lt;callback_emit_type&lt;ASYNC&gt;, void()&gt;
  template &lt;typename... Args&gt;
  struct construct_callback_impl&lt;typename std::enable_if&lt;is_emit_type_t&lt; typename std::tuple_element_t&lt;0, std::tuple&lt;Args...&gt; &gt;::type &gt;::value&gt;::type, Args...&gt;
  {
      //alias on implementation
      using type = int; //temporary stub
  };
  </code></pre>
  
  <p>BUT now I get the:</p>
  
  <pre><code>error C2338: tuple index out of bounds
  note: see reference to class template instantiation 'std::tuple_element&lt;0,std::tuple&lt;&gt;&gt;' being compiled
  </code></pre>