8

max(x, y)以下の式の呼び出しのオーバーロード解決によりreturn max(max(x, y), z);、非テンプレート関数が呼び出されるのはなぜchar const* max(char const*, char const*)ですか?

私が理解できる限り、機能はmax<const char*>(x, y)前者よりも適合しています。xconst char* const&yconst char* const&

#include <iostream>

template <typename T>
T const& max (T const& x, T const& y)
{
    return x < y ? y : x;
}

char const* max (char const* x, char const* y)
{
    return std::strcmp(x, y) < 0 ? y : x;
}

template <typename T>
T const& max (T const& x, T const& y, T const& z)
{
    return max (max(x, y), z);
}

int main ()
{
    const char* sx = "String_x";
    const char* sy = "String_y";
    const char* sz = "String_z";
    max(sx, sy, sz);
}
4

1 に答える 1

4

max(x, y)以下の式の呼び出しの過負荷解決によりreturn max(max(x, y), z);、非テンプレート関数が呼び出されるのはなぜchar const* max(char const*, char const*)ですか?

この関数を呼び出す場合:

template <typename T>
T const& max (T const& x, T const& y, T const& z)
{
    return max (max(x, y), z);
}

Tと推定されますconst char*。したがって、この署名はインスタンス化されます。

const char* const& max (
    const char* const& x, 
    const char* const& y, 
    const char* const& z
    )

max()この関数は、タイプが引数を持つのバイナリバージョンを内部的に呼び出しますconst char*。テンプレートと非テンプレートの両方のオーバーロードは、タイプの引数に対して実行可能ですconst char*

ただし、2つの関数が呼び出しを解決するために実行可能であり、そのうちの1つがテンプレートではない場合、非テンプレートバージョンが最適であると見なされます。

C++11規格のパラグラフ13.3.3/1による:

これらの定義を前提として、**すべての引数iについて、ICSi(F1)がICSi(F2)よりも悪い変換シーケンスではない場合、**実行可能な関数F1は別の実行可能な関数F2よりも優れた関数であると定義されます。

—一部の引数jの場合、ICSj(F1)はICSj(F2)よりも優れた変換シーケンスです。そうでない場合は、

—コンテキストは、ユーザー定義の変換(8.5、13.3.1.5、および13.3.1.6を参照)による初期化と、F1の戻りタイプから宛先タイプ(つまり、初期化されるエンティティのタイプ)への標準変換シーケンスです。 F2の戻りタイプから宛先タイプへの標準変換シーケンスよりも優れた変換シーケンスです。[...]または、そうでない場合は、

F1は非テンプレート関数であり、F2は関数テンプレートの特殊化です。そうでない場合は、

— F1とF2は関数テンプレートの特殊化であり、F1の関数テンプレートは、14.5.6.2で説明されている半順序規則に従って、F2のテンプレートよりも特殊化されています。

これは、非テンプレートのオーバーロードが選択される理由を説明しています。

于 2013-03-23T12:05:37.737 に答える