title: boost::enable_if MSVC
body: <p>I have code, that compiles and runs as expected in <code>gcc</code> and doesn't compile in <code>MSVC 2012 RC</code>, i can't explain why, so it's bug in <code>MSVC</code>, or my code is incorrect?</p>
  
  <pre><code>#include &lt;boost/mpl/vector.hpp&gt;
  #include &lt;boost/mpl/front.hpp&gt;
  #include &lt;boost/mpl/is_sequence.hpp&gt;
  #include &lt;boost/mpl/size.hpp&gt;
  #include &lt;boost/utility/enable_if.hpp&gt;
  #include &lt;vector&gt;
  #include &lt;iostream&gt;
  
  namespace mpl = boost::mpl;
  
  template&lt;typename T,
  typename = void&gt;
  struct Some
  {
     typedef std::vector&lt;T&gt; type;
  };
  
  template&lt;typename T&gt;
  struct Some&lt;T, typename boost::enable_if_c&lt;mpl::is_sequence&lt;T&gt;::type::value&gt;::type&gt; :
      public Some&lt;typename mpl::front&lt;T&gt;::type&gt;::type
  {
  };
  
  
  int main()
  {
     typedef mpl::vector&lt;int, double&gt; vect_t;
     typedef Some&lt;vect_t&gt; vector;
     vector vect;
     vect.push_back(1);
     std::cout &lt;&lt; "int: " &lt;&lt; vect.at(0) &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p><a href="http://liveworkspace.org/code/45d78872a2c7f30192277a81c655b471" rel="nofollow">http://liveworkspace.org/code/45d78872a2c7f30192277a81c655b471</a></p>
  
  <p>MSVC says, that <code>push_back</code> and <code>at</code> are not members of <code>Some&lt;vect_t&gt;</code>.</p>
  
  <p><strong>EDIT.</strong></p>
  
  <p>It looks like bug in MSVC 2012 since</p>
  
  <pre><code>#include &lt;boost/mpl/vector.hpp&gt;
  #include &lt;boost/mpl/front.hpp&gt;
  #include &lt;boost/mpl/is_sequence.hpp&gt;
  #include &lt;boost/mpl/size.hpp&gt;
  #include &lt;boost/utility/enable_if.hpp&gt;
  #include &lt;vector&gt;
  #include &lt;iostream&gt;
  
  namespace mpl = boost::mpl;
  
  template&lt;typename T, typename = void&gt;
  struct Some
  {
      typedef std::vector&lt;T&gt; type;
  };
  
  template&lt;typename T&gt;
  struct Some&lt;T, typename boost::enable_if_c&lt;mpl::is_sequence&lt;T&gt;::type::value&gt;::type&gt; :
      public std::vector&lt;int&gt;
  {
  };
  
  
  int main()
  {
     typedef mpl::vector&lt;int, double&gt; vect_t;
     typedef Some&lt;vect_t&gt;::type vector;
     vector vect;
     vect.push_back(1);
     std::cout &lt;&lt; "int: " &lt;&lt; vect.at(0) &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>gives errors, that i can't <code>push_back</code> <code>int</code> into <code>std::vector&lt;boost::mpl::vector&lt;int, double&gt; &gt;</code>, so it choose general-case, not specialization...</p>
  
  <p><strong>EDIT.</strong></p>
  
  <p>Strange... But this works as expected</p>
  
  <pre><code>template&lt;typename T&gt;
  struct Some&lt;T, typename std::enable_if&lt;boost::mpl::is_sequence&lt;T&gt;::value&gt;::type&gt; :
      public std::vector&lt;int&gt;
  {
  };
  </code></pre>
  
  <p>So, i can't explain why, but MSVC 2012 cannot works with nested expressions in enable_if (or possibly in template parameters).</p>
  
  <pre><code>template&lt;typename T&gt;
  struct is_int : public std::integral_constant&lt;bool, false&gt;
  {
  };
  
  template&lt;&gt;
  struct is_int&lt;int&gt; : public std::integral_constant&lt;bool , true&gt;
  {
  };
  
  template&lt;typename T, typename = void&gt;
  struct Some
  {
      typedef void type;
  };
  
  template&lt;typename T&gt;
  struct Some&lt;T, typename std::enable_if&lt;is_int&lt;T&gt;::type::value&gt;::type&gt;
  {
      static_assert(is_int&lt;int&gt;::type::value, "asserted");
      typedef T type;
  };
  
  int main()
  {
      static_assert(is_int&lt;T&gt;::type::value, "ass");
      Some&lt;int&gt;::type t = 0;
  }
  </code></pre>