title: Can you static_assert a tuple has only one type satisfying a particular condition?
body: <p>This code gets the first tuple element satisfying a test (in this case, if it derives <code>Base</code>). <strong>How can I static_assert that only one element satisfying that condition may exist?</strong> (much like C++17's <code>std::get&lt;class&gt;</code> fails to compile if there exists more than one element of the provided typename.)</p>
  
  <pre><code>template&lt;class...&gt;
  struct voider { using type = void; };
  
  template&lt;class...Ts&gt;
  using void_t = typename voider&lt;Ts...&gt;::type;
  
  template&lt;template&lt;class...&gt; class Test, class Tuple&gt;
  struct get_first_pass;
  
  template&lt;template&lt;class...&gt; class Test, class Tuple&gt;
  using get_first_pass_t = typename get_first_pass&lt;Test, Tuple&gt;::type;
  
  template&lt;template&lt;class...&gt; class, class, class...&gt;
  struct first_pass {};
  
  template&lt;template&lt;class...&gt; class Test, class T0, class...Ts&gt;
  struct first_pass&lt;Test, std::enable_if_t&lt;!Test&lt;T0&gt;::value&gt;, T0, Ts...&gt; :
    first_pass&lt;Test, void, Ts...&gt;
  {};
  
  template&lt;template&lt;class...&gt; class Test, class T0, class...Ts&gt;
  struct first_pass&lt;Test, std::enable_if_t&lt;Test&lt;T0&gt;::value&gt;, T0, Ts...&gt; {
    using type = T0;
  };
  
  template&lt;template&lt;class...&gt; class Test, template&lt;class...&gt; class Tuple, class...Ts&gt;
  struct get_first_pass&lt;Test, Tuple&lt;Ts...&gt;&gt; : first_pass&lt;Test, void, Ts...&gt;
  {};
  
  template&lt;class Base&gt;
  struct is_derived_from {
    template&lt;class Derived&gt;
    using test = std::is_base_of&lt;std::decay_t&lt;Base&gt;, std::decay_t&lt;Derived&gt;&gt;;
  };
  
  template&lt;class Base, class Tuple&gt;
  using get_first_derived =
    get_first_pass_t&lt;is_derived_from&lt;Base&gt;::template test, Tuple&gt;;
  
  template&lt;class Base, class Tuple&gt;
  auto get_from_base(Tuple&amp;&amp; tuple)
  -&gt; decltype(std::get&lt; get_first_derived&lt;Base, std::decay_t&lt;Tuple&gt;&gt; &gt;(
                                                    std::forward&lt;Tuple&gt;(tuple))) {
    return std::get&lt; get_first_derived&lt;Base, std::decay_t&lt;Tuple&gt;&gt; &gt;(
                                                    std::forward&lt;Tuple&gt;(tuple));
  }
  </code></pre>