ホームページ >バックエンド開発 >C++ >C のオーバーロード解決において、ポインタの減衰が推定されたテンプレートよりも優先されるのはなぜですか?

C のオーバーロード解決において、ポインタの減衰が推定されたテンプレートよりも優先されるのはなぜですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-11-29 19:15:15915ブラウズ

Why Does Pointer Decay Take Precedence Over Deduced Templates in C   Overload Resolution?

ポインタの減衰と推定されたテンプレート: 優先順位のパズルを解く

C の領域では、関数のオーバーロードとテンプレートの推定の間の相互作用は次のようになります。時には予期せぬ結果を招くこともあります。代表的な例は、配列と生のポインターの両方を処理するために関数がオーバーロードされた場合に発生します。次のコードを考えてみましょう。

template <size_t n>
void foo(const char (&s)[N]) {
    std::cout <p>この関数は、最初は配列の長さを出力するために考案されましたが、非配列をサポートするように拡張されました。しかし、この拡張は不可解な曖昧さをもたらします。</p>
<pre class="brush:php;toolbar:false">foo("hello") // now prints raw, size=5

後者の方がパラメータとより正確に一致しているにもかかわらず、意図した「配列」バージョンではなく「生」オーバーロードが選択されるのはなぜでしょうか?答えは、ポインターの減衰 として知られる微妙な概念にあります。

ポインターの減衰は、配列から対応するポインターへの暗黙的な変換です。この場合、配列「hello」は、その最初の要素への const char * ポインターにサイレントに変換されます。結果として、ポインターを処理するオーバーロードが優先されます。

この動作は、 C での変換のコストに起因します。オーバーロードは、引数をパラメーターに変換するコストを最小限に抑えるために評価されます。この場合、配列からポインターへの変換は、配列から関数へのパラメーター変換よりもコストが低くなります。

この問題を回避するには、2 番目のオーバーロードもテンプレートとして定義できます。

template <typename t>
auto foo(T s)
-> std::enable_if_t<:is_convertible char const>{}>
{
    std::cout <p>このアプローチでは、ポインター減衰変換が不要になるため、テンプレート バージョンが優先されます。</p>
<p>結論として、ポインター減衰が優先されます。推定されたテンプレートを超えることは、過負荷解決におけるコスト最小化原則の結果です。あいまいさを回避するには、関数をオーバーロードするときに暗黙的な変換とオーバーロードの種類の両方を考慮することが重要です。</p></:is_convertible></typename>

以上がC のオーバーロード解決において、ポインタの減衰が推定されたテンプレートよりも優先されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。