6

C++ Primerには、関数テンプレートのオーバーロードに関する例があります。

// print any type we don't otherwise handle
template <typename T> string debug_rep(const T &t)
{
    cout << "debug_rep(T const&)\n";
    ostringstream ret; // see § 8.3 (p. 321)
    ret << t; // uses T's output operator to print a representation of t
    return ret.str(); // return a copy of the string to which ret is bound
}

// print pointers as their pointer value, followed by the object to which the pointer points
// NB: this function will not work properly with char*; see § 16.3 (p. 698)
template <typename T> string debug_rep(T *p)
{
    std::cout << "debug_rep(T*)\n";
    ostringstream ret;
    ret << "pointer: " << p << '\n';         // print the pointer's own value
    if (p)
        ret << " " << debug_rep(*p); // print the value to which p points
    else
        ret << " null pointer";      // or indicate that the p is null
    return ret.str(); // return a copy of the string to which ret is bound
}

ポインターを指定して debug_rep を呼び出すと、次のようになります。

cout << debug_rep(&s) << endl;

両方の関数が実行可能なインスタンス化を生成します。

  • debug_rep(const string* &)Tにバインドされたdebug_rep の最初のバージョンのインスタンス化です。string*

  • debug_rep(string*)debug_repTバインドされた の 2 番目のバージョンのインスタンス化です。string*

の 2 番目のバージョンのインスタンス化は、debug_repこの呼び出しと完全に一致します。

最初のバージョンのインスタンス化では、プレーン ポインターを へのポインターに変換する必要がありますconst。通常の関数の一致では、2 番目のテンプレートを優先する必要があり、実際にそれが実行されます。

しかし、文字列へのポインターを宣言すると、const変換は行われず、2 番目のバージョンが常に選択されます。

    string const s("hi"); // const
    cout << debug_rep(&s) << '\n';

だから私はそれが本の間違いだと思います.バージョンはポインタを取るかどうかを渡すので、バージョンが好ましいconstと思いTます.std::string const*std::string*

どう思いますか?

4

1 に答える 1