title: Is visual c++ std::isfinite() standard conforming?
body: <p>I got a wrapper class that has a simple and light-weighted implicit conversion operator to <code>double</code>.</p>
  
  <p>I like to use it as I would use a double, for example:</p>
  
  <pre><code>if (!std::isfinite(myVar)) ...
  </code></pre>
  
  <p>But visual c++ implementation of <code>std::isfinite(double)</code> is actually a template that get his argument by copy.</p>
  
  <p>So my wrapper class copy constructor is called, and it is not light-weighted.</p>
  
  <p>To avoid this, I have to write:</p>
  
  <pre><code>if (!std::isfinite((double)myVar)) ...
  </code></pre>
  
  <p>for <em>every call</em> :(</p>
  
  <p>If visual c++ <code>std::isfinite()</code> was defined as is it on <a href="http://en.cppreference.com/w/cpp/numeric/math/isfinite" rel="nofollow">cppreference.com</a>, I would not have to cast every call: ([<em>edit</em>] I may be wrong, Integral isn't an actual type... but... [<em>edit</em>] It still should not accept user defined types ?)</p>
  
  <pre><code>bool isfinite( float arg );
  bool isfinite( double arg );
  bool isfinite( long double arg );
  bool isfinite( Integral arg );
  </code></pre>
  
  <p>I am not sure what the standard says about this. 
  Is vc++ template <code>std::isfinite</code> standard-conforming ?</p>
  
  <p>Should I report this as a bug on Microsoft connect ?</p>
  
  <p>Should I define my own <code>isfinite(double)</code> that calls <code>std::isfinite</code> ?</p>
  
  <h2>edit</h2>
  
  <p>Or maybe it is a non-issue as in a release build the calls get inlined and no copy occurs ? (well I'll try to check it right now and update in a few minutes)</p>
  
  <h2>edit 2</h2>
  
  <p>It doesn't seem to get inlined in a release build with /Ob2 (inline any suitable function)</p>
  
  <h2>edit 3</h2>
  
  <p>as requested, a sample:</p>
  
  <pre><code>struct DoubleWrapper {
  
    double value;
  
    DoubleWrapper(double value) : value(value) {
      printf("copy Ctor\n");
    }
  
    DoubleWrapper(const DoubleWrapper &amp; that) : value(that.value) {}
  
    operator double() const {
      return this-&gt;value;
    }
  };
  
  int main() {
  
    DoubleWrapper a(rand());      //rand to prevent optimization
  
    auto res = std::isfinite(a);
  
    printf("%d", res);            //printf to prevent optimization
  }
  </code></pre>
  
  <h2>edit 4</h2>
  
  <p>So, based on Ben Voigt comment, this is what I added to my class header:</p>
  
  <pre><code>#include &lt;cmath&gt;
  
  namespace std {
      inline bool isfinite(const DoubleWrapper&lt;double&gt; &amp; dw) {
          return isfinite((double)dw);
      }
  }
  </code></pre>
  
  <p>Is this a correct solution ?</p>
  
  <p>The only thing is, should I do the same for all <code>&lt;cmath&gt;</code> functions that takes a double ?</p>
  
  <h2>edit 5</h2>
  
  <p>I'm responding to Shafik Yaghmour answer here, because a comment is too limited (maybe I should start a new question)</p>
  
  <p>If I understand correctly, instead of my edit 4, I should add this to my class header:</p>
  
  <pre><code>inline bool isfinite(const DoubleWrapper&lt;double&gt; &amp; dw) {
      return isfinite((double)dw);
  }
  
  using std::isfinite;
  </code></pre>
  
  <p>Is it required to put it in a namespace, or can I leave it in the "global" namespace ?</p>
  
  <p>But this mean I have to change all my calls from <code>std::isfinite(dw)</code> to <code>isfinite(dw)</code>.</p>
  
  <p>Ok, but I realize there are many things I don't understand.
  I am confused.</p>
  
  <p>I understand that adding an <em>overload</em> to std is not allowed. </p>
  
  <p>However, adding a template specialization is allowed ? Why ? What difference does it makes ?</p>
  
  <p>Anyway, I tried it, and it is not a solution to my problem because this specialization:</p>
  
  <pre><code>template&lt;&gt; inline __nothrow bool std::isfinite(const MagicTarget&lt;double&gt; &amp; mt) {
      return std::isfinite((double)mt);
  }
  </code></pre>
  
  <p>will not be selected by the compiler over the standard one:</p>
  
  <pre><code>template&lt;class _Ty&gt; inline __nothrow bool isfinite(_Ty _X)
  {
      return (fpclassify(_X) &lt;= 0);
  }
  </code></pre>
  
  <p>To be selected, it should be </p>
  
  <pre><code>template&lt;&gt; inline __nothrow bool std::isfinite(MagicTarget&lt;double&gt; mt) {
      return std::isfinite((double)mt);
  }
  </code></pre>
  
  <p>But this would still call the copy Ctor :(</p>
  
  <p>Surprisingly the overload (see edit 4) is selected over the standard template...
  I am beginning to think that some C++ rules are too subtle for me :(</p>
  
  <p>But, to begin with, why on earth are cmath functions and especially <code>std::isfinite</code> a template ?</p>
  
  <p>What's the point of accepting anything else that floating points types ?</p>
  
  <p>Anyway, vc++ <code>std::isfinite</code> calls <code>std::fpclassify</code> that is only defined for float, double and long double.
  So... What's the point?</p>
  
  <p>I am thinking the standard committee screwed up by allowing cmath functions to be templates. They should only be defined for the types that are relevant, or maybe takes their arguments as universal references.</p>
  
  <p>That's it, sorry for the rant...</p>
  
  <p>I will go for the (not in std) overload.
  Thank you!</p>