std::reference_wrapperがないoperator<ため、唯一の方法はメンバーref_wrapper<ref_wrapperを介することです。ref_wrapper
operator T& () const noexcept;
ご存知のように、次のとおりですstd::string。
typedef basic_string<char> string;
関連する宣言string<stringは次のとおりです。
template<class charT, class traits, class Allocator>
bool operator< (const basic_string<charT,traits,Allocator>& lhs,
const basic_string<charT,traits,Allocator>& rhs) noexcept;
このstring<string関数宣言テンプレートは、一致するstring=によってインスタンス化され、これは=などbasic_string<charT,traits,Allocator>に解決されます。charTchar
std::reference_wrapper(またはその (ゼロ) 基底クラスのいずれか) が一致しないためbasic_string<charT,traits,Allocator>、関数宣言テンプレートを関数宣言にインスタンス化できず、オーバーロードに参加できません。
ここで重要なのは、非テンプレートプロトタイプがないことです。operator< (string, string)
問題を示す最小限のコード
template <typename T>
class Parametrized {};
template <typename T>
void f (Parametrized<T>);
Parametrized<int> p_i;
class Convertible {
public:
operator Parametrized<int> ();
};
Convertible c;
int main() {
f (p_i); // deduce template parameter (T = int)
f (c); // error: cannot instantiate template
}
与える:
In function 'int main()':
Line 18: error: no matching function for call to 'f(Convertible&)'
標準引用
14.8.2.1 関数呼び出しからのテンプレート引数の推定 [temp.deduct.call]
テンプレート引数推定は、以下で説明するように、各関数テンプレート パラメーターの型 (call it P) と呼び出しの対応する引数の型 (call it ) を比較することによって行われAます。
(...)
一般に、演繹プロセスは、演繹されたものを (上記のように型が変換された後に)A同一にするテンプレート引数値を見つけようとします。ただし、違いが認められる 3 つのケースがあります。AA
- 元
Pの型が参照型の場合、推論されAた型 (つまり、参照によって参照される型) は、変換された型よりも cv 修飾されている可能性がありますA。
これは の場合であることに注意してくださいstd::string()<std::string()。
- 変換されたものは、修飾変換 (4.4) を介して推定に変換
Aできる別のポインターまたはメンバー型へのポインターにすることができます。A
以下のコメントを参照してください。
- が
PクラスでP、形式がsimple-template-idの場合、変換Aされた は deduced の派生クラスになることができますA。
コメント
これは、この段落で次のことを意味します。
14.8.1 明示的なテンプレート引数指定 [temp.arg.explicit] /6
暗黙的な変換 (第 4 節) は、関数の引数に対して実行され、対応する関数パラメーターの型に変換されます (パラメーターの型に、テンプレート引数推定に関与するテンプレート パラメーターが含まれていない場合)。
ifは、前に引用したテキストと直接矛盾するため、 if および only if と見なすべきではありません。