title: Unexpected results when using std::is_assignable, boost::function, and nullptr
body: <p>The following expression using <code>is_assignable</code> returns <code>true</code> when using gcc 4.7 and boost 1.49:</p>
  
  <pre><code>typedef boost::function&lt;void()&gt; F;
  std::is_assignable&lt;F, std::nullptr_t&gt;::value
  </code></pre>
  
  <p>However, this code fails to compile:</p>
  
  <pre><code>boost::function&lt;void()&gt; f;
  f = nullptr;
  </code></pre>
  
  <p>producing these error messages:</p>
  
  <pre><code>In file included from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/detail/maybe_include.hpp:13:0,
               from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/detail/function_iterate.hpp:14,
               from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/preprocessor/iteration/detail/iter/forward1.hpp:47,
               from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function.hpp:64,
               from ..\main.cpp:8:
  c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp: In instantiation of 'static void boost::detail::function::void_function_obj_invoker0&lt;FunctionObj, R&gt;::invoke(boost::detail::function::function_buffer&amp;) [with FunctionObj = std::nullptr_t; R = void]':
  c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:907:60:   required from 'void boost::function0&lt;R&gt;::assign_to(Functor) [with Functor = std::nullptr_t; R = void]'
  c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:722:7:   required from 'boost::function0&lt;R&gt;::function0(Functor, typename boost::enable_if_c&lt;boost::type_traits::ice_not&lt;boost::is_integral&lt;Functor&gt;::value&gt;::value, int&gt;::type) [with Functor = std::nullptr_t; R = void; typename boost::enable_if_c&lt;boost::type_traits::ice_not&lt;boost::is_integral&lt;Functor&gt;::value&gt;::value, int&gt;::type = int]'
  c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:1042:16:   required from 'boost::function&lt;R()&gt;::function(Functor, typename boost::enable_if_c&lt;boost::type_traits::ice_not&lt;boost::is_integral&lt;Functor&gt;::value&gt;::value, int&gt;::type) [with Functor = std::nullptr_t; R = void; typename boost::enable_if_c&lt;boost::type_traits::ice_not&lt;boost::is_integral&lt;Functor&gt;::value&gt;::value, int&gt;::type = int]'
  c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:1083:5:   required from 'typename boost::enable_if_c&lt;boost::type_traits::ice_not&lt;boost::is_integral&lt;Functor&gt;::value&gt;::value, boost::function&lt;R()&gt;&amp;&gt;::type boost::function&lt;R()&gt;::operator=(Functor) [with Functor = std::nullptr_t; R = void; typename boost::enable_if_c&lt;boost::type_traits::ice_not&lt;boost::is_integral&lt;Functor&gt;::value&gt;::value, boost::function&lt;R()&gt;&amp;&gt;::type = boost::function&lt;void()&gt;&amp;]'
  ..\main.cpp:172:6:   required from here
  c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:153:11: error: '* f' cannot be used as a function
  </code></pre>
  
  <p>Additionally, this expression returns <code>false</code>:</p>
  
  <pre><code>typedef boost::function&lt;void()&gt; G;
  std::is_assignable&lt;G, decltype(NULL)&gt;::value
  </code></pre>
  
  <p>but this code does compile:</p>
  
  <pre><code>boost::function&lt;void()&gt; g;
  g = NULL;
  </code></pre>
  
  <p>The results of <code>is_assignable</code> don't seem to properly reflect the functionality of <code>boost::function</code>.  Am I doing something wrong here?  (I'm having trouble making sense of the error messages.)</p>
  
  <p>I thought the type traits were supposed to be a reliable way of determining the functionality of the classes used in templates.  Are the type traits provided in C++11 simply incompatible with boost::function?</p>
  
  <hr>
  
  <p>To give this some context, I've been working on several personal projects to better familiarize myself with the new features of C++11.  For this particular project, I'm attempting to create a class that stores a callable function that can be "deactivated".  This is roughly what I'm trying to do:</p>
  
  <pre><code>template &lt;typename F&gt;
  class callable_function
  {
  public:
      callable_function(F func) : func_(func)
      {
          /* func_ is initially active */
      }
  
      void call()
      {
          if (/* func_ is active */) func_();
      }
  
      void deactivate()
      {
          /* set func_ to deactive */
      }
  
  private:
      F func_;
  };
  </code></pre>
  
  <p>For the <code>/* func_ is active */</code> and <code>/* set func_ to deactive */</code> blocks, I want to provide two different implementations that are selected at compile time depending on the properties of <code>F</code>.  If <code>nullptr</code> can be assigned to <code>func_</code> and <code>func_</code> can be used in a boolean context, then I want to use the following (which is what gets selected for built-in function pointers and <code>std::function</code>):</p>
  
  <pre><code>template &lt;typename F&gt;
  class callable_function
  {
  public:
      callable_function(F func) : func_(func) {}
  
      void call()
      {
          if (func_) func_();
      }
  
      void deactivate()
      {
          func_ = nullptr;
      }
  
  private:
      F func_;
  };
  </code></pre>
  
  <p>If <code>nullptr</code> cannot be assigned to <code>func_</code>, then I want to store an additional boolean value within the class that stores the "active" status.  This implementation is selected for functors and lambda functions:</p>
  
  <pre><code>template &lt;typename F&gt;
  class callable_function
  {
  public:
      callable_function(F func) : func_(func), active_(true) {}
  
      void call()
      {
          if (active_) func_();
      }
  
      void deactivate()
      {
          active_ = false;
      }
  
  private:
      F func_;
      bool active_;
  };
  </code></pre>
  
  <p>Since <code>nullptr</code> currently cannot be assigned to <code>boost::function</code>, I would expect the second implementation to be chosen.  However, since <code>is_assignable</code> is returning <code>true</code> for <code>boost::function</code> and <code>nullptr</code>, the first implementation is selected instead, which results in a compilation error in the <code>deactivate</code> function.</p>