9

C++ 03 では、 eg を使用すると、 を使用std::pow(double_val, 6)するよりもかなり高速std::pow(double_val, 6.0)でした。

これは、C++11 でコンパイルする場合には当てはまりません。gcc の libstdc++-4.8 の cmath ヘッダーを見ると、明示的な pow(double, int) がもはや存在しないことがわかります。このケースは、int を double に昇格させる次のテンプレートによって処理されます。

template<typename _Tp, typename _Up>
inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
pow(_Tp __x, _Up __y) {
  typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
  return std::pow(__type(__x), __type(__y));
}

これは C++11 標準の動作ですか、それとも将来の libstdc++ 実装がより高速な方法に戻る可能性がありますか?

第二に、標準または実装上の理由により、より高速な動作が不可能になった場合、それを再び達成するための最も移植性の高い方法は何ですか? power(...)「ext/numeric」の下に gcc stdlibc++の関数が表示されますが、これは非標準のSGI(rip) 拡張機能としてマークされています。

4

2 に答える 2

2

C は単にdouble pow(double, double)オーバーロードを提供します (C では関数のオーバーロードが許可されていないことを思い出してください)。C++11 標準 (26.8/9) では、次のオーバーロードが (C に加えて) namespace に追加されると述べていますstd

float pow(float, float);
long double pow(long double, long double);

したがって、double pow(double, int)標準関数ではなく拡張機能です。したがって、実装によってそれが提供される場合と提供されない場合があります。

クリスチャン・ラウのコメントと回答の後に編集します。

今、私は過負荷がそこにあるに違いないと信じています。したがって、過負荷が発生するはずdouble pow(double, int)です。ただし、このオーバーロードは (彼の答えで彼が言っているように) を a にキャストintし、doubleを呼び出さなければなりませんdouble pow(double, double)

実はオーバーロードが多い。それらを提供する最も簡単な方法は、通常の関数としてではなく、OP に示されている libstdc++ 実装とまったく同じテンプレート関数として提供することです。

Howard Hinnant が詳細を説明しているこの未解決の問題も参照してください。

最後に、Hulk によって提供されたリンクintは非常に関連性が高く、Howard Hinnant は (再び) を にキャストすることとは異なることを行う最適化されたオーバーロードを提供する理由はほとんどないと説明していdoubleます。

于 2013-09-18T13:20:44.970 に答える