問題は、推定が開始される前にテンプレートの関数パラメーターの 1 つが参照型でない場合、そのパラメーターは参照型に推定されないことです。したがって、左側の演繹ではがT
得られますint
が、右側の演繹では がT
得られint&
ます。これは不一致であり、コンパイラは文句を言います。
最善の方法は、関数パラメーターを関数ポインターのパラメーターの型と同じ型にすることです。
template<typename T> struct identity { typedef T type; };
template<typename T>
void f(typename identity<T>::type t, void (*func)(T)) {}
を使用identity<T>::type
すると、左側の控除が無効になります。がT
右側で決定さT
れると、左側に代入され、最終的なパラメーターの型が生成されます。
テンプレート パラメーターとして右側を使用することを提案した人がいますoperator()
。オーバーロードされた関数オブジェクトを受け入れることができるため、これは良いことです。しかし、参照が必要かどうかを知る必要があるという問題に直面します。それを解決するために、boost
持っていますreference_wrapper
(ちなみに、上記のテンプレートboost
もあります)。identity
template<typename T, typename F>
void f(T t, F func) {}
ここで、コピーではなく参照を渡したい場合は、次のようにすることができます
int i;
f(boost::ref(i), some_function);
ref
に暗黙的に変換可能な reference_wrapper オブジェクトを返しますT&
。したがって、 を呼び出すfunc(t)
と、t
は自動的にターゲット参照に変換されます。参照を渡したくない場合は、i
直接渡します。