4

関数 func と func と同じ型のパラメーター t を取るファンクター f があります。コンパイル エラーのため、g を f に渡すことができません ( の呼び出しに一致する関数がありませんf(int&, void (&)(int&)))。g が非参照パラメーター g(int s) を取る場合、コンパイルは終了します。または、手動でテンプレート パラメータを指定するf<int&>(i, g)と、コンパイルも終了します。

template<typename T>
void f(T t, void (*func)(T)) {}

void g(int& s) {}

int main(int, char*[])
{
    int i = 7;

    f(i, g); // compilation error here

    return 0;
}

控除を機能させるにはどうすればよいですか?

4

4 に答える 4

6

次のように関数を呼び出すことができます。

f<int&>(i, g);

しかし今、私も参照によって渡されます。

一般に、関数もテンプレート型にします。

template <typename T, typename F>
void f(T t, F func) 
{ 
    func(t); //e.g
}
于 2010-03-29T16:04:41.033 に答える
5

私はあなたがどちらかを必要とすると思います:

void f(T t, void (*func)(T&)) {}

また:

void g(int s) {}

でも私は〜がいい:

template<typename T, typename T2> 
void f(T t, T2 func) {}

これは関数とファンクターで機能するためです。

于 2010-03-29T16:03:04.577 に答える
5

問題は、推定が開始される前にテンプレートの関数パラメーターの 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直接渡します。

于 2010-03-29T20:19:20.637 に答える
1
template<typename T>
void f(T t, void (*func)(T)) {}

ここで重要なことはT、両方の引数で使用したことです。つまり、型が正確に一致する必要があります。

void g(int& s) {}

int i = 7;
f(i, g);

コードでは、 tointを取る関数とを渡します。これらは異なるタイプですが、テンプレートは同じタイプの 2 つを想定しています。他の人が提案したように、最も簡単な修正は、関​​数もテンプレートにすることです。int&f()f

template <typename T, typename F>
void f(T t, F func) 
{ 
    func(t);
}
于 2010-03-29T16:11:39.830 に答える