title: Implementing the Linux Kernel's __is_constexpr (ICE_P) macro in pure C++
body: <p>After <a href="https://stackoverflow.com/questions/49480442/detecting-integer-constant-expressions-in-macros">reading about</a> the standard C11 version of Martin Uecker's <code>ICE_P</code> predicate, I tried to implement it in pure C++. The C11 version, making use of <code>_Generic</code> selection is as follows:</p>
  
  <pre><code>#define ICE_P(x) _Generic((1? (void *) ((x)*0) : (int *) 0), int*: 1, void*: 0)
  </code></pre>
  
  <p>The obvious approach for C++ is to replace <code>_Generic</code> by a template and <code>decltype</code>, such as:</p>
  
  <pre><code>template&lt;typename T&gt; struct is_ice_helper;
  template&lt;&gt; struct is_ice_helper&lt;void*&gt; { enum { value = false }; };
  template&lt;&gt; struct is_ice_helper&lt;int*&gt;  { enum { value = true  }; };
  
  #define ICE_P(x) (is_ice_helper&lt;decltype(1? (void *) ((x)*0) : (int *) 0)&gt;::value)
  </code></pre>
  
  <p>However, it fails the <a href="https://wandbox.org/permlink/5f3fvSHya0bYtfPs" rel="noreferrer">simplest test</a>. Why can't it detect integer constant expressions?</p>