3

2 つのオーバーロードされた関数を定義しました。それらの宣言は次のとおりです。

template <class T> void Foo(const T *p);    // lets call this Foo_p

template <class T> void Foo(const T& r);    // lets call this Foo_r

電話すると

Foo( ptr_to_non_const );

Foo_r呼ばれます。最適な一致を探すときに、定数修飾がポインターから取り除かれると想定しました。というのは予想T*以上に専門的なので。T&Foo_p

テンプレートの引数推定規則と一致の優先順位をリストした優れたリソースを教えてください。

この特定のケースtemplate <class T> void Foo(const T& r)では、非ポインター型で呼び出される予定です。const修飾の有無にかかわらず関数を定義する必要があるということですか。1 つの引数については大したことではありませんが、私の関数は複数のポインターを使用するため、繰り返しを避けたいと思います。任意の提案をいただければ幸いです。

4

1 に答える 1

3

テンプレート演繹規則は非常に複雑で、どこかに簡単な要約があるかどうかわかりません。ただし、2 つのテンプレートが候補であり、そのうちの 1 つが変換を必要とし、もう 1 つが必要でない場合は、テンプレート引数を生成するために変換を必要としない方が選択されます。あなたの例では、一致するインスタンス化は次のとおりです。

S* ptr_to_non_const = ...;
Foo(ptr_to_non_const); // => candidates:
                       //   a. F(const T&) with `T` deduced as `S*` requires no
                       //      conversion
                       //   b. F(const T*) with `T` deduced as `S` requires `S*` to
                       //      `S const*` conversion

std::enable_if<...>ポインター オーバーロードの使用を強制するには、次のように使用して、オーバーロード セットから参照バージョンを削除できますstd::is_pointer<...>

template <class T>
typename std::enable_if<!std::is_pointer<T>::value>::type
Foo(const T& r);

これは C++ 2011 の機能を使用していますが、両方ともstd::enable_if<...>C std::is_pointer<...>++ 2003 コンパイラで非常に簡単に実装できます ( Boostがそうしていると確信しています)。

于 2012-12-02T02:01:43.187 に答える