0

C++ でアルゴリズム ライブラリの変換関数を使用すると問題が発生します。単項テンプレート関数で使用したいのですが、これは、変換関数が 3 つのイテレータと関数を引数として必要とすることを意味します。しかし、プログラムがクラッシュし、関数が単項演算でありバイナリ演算ではないため、意味をなさない引数が欠落しているとコンパイラが通知します。

私のコードは次のとおりです。

template <typename T>
T reciprocal ( T value )
{ return (T)1/value ; }

int main()
{
    vector<int> vec(5, 2);
    transform(vec.begin(), vec.end(), vec.begin(), reciprocal);
}

変換を含むテンプレートの使用は禁止されていますか?

4

3 に答える 3

2

reciprocalは関数テンプレートであり、std::transform使用する特定の特殊化を特定できません。明示的にテンプレート パラメータを指定する必要があります。

transform(vec.begin(), vec.end(), vec.begin(), reciprocal<int>);

あなたの場合、整数除算を実行することに注意してください1/2。これにより、一連のゼロが得られます。浮動小数点の逆数計算と、 のテンプレート パラメータが でreciprocal使用されるものと同じである必要がないことを説明するためにvec、次のことを試してください。

std::vector<double> vec2;
std::transform(vec.begin(), 
               vec.end(), 
               std::back_inserter(vec2), 
               reciprocal<double>);

これにより、vec25 つの値が含まれることになり0.5ます。

于 2013-07-18T16:09:09.093 に答える
1

しかし、私のプログラムはクラッシュし、コンパイラは、関数が単項演算でありバイナリ演算ではないため、意味をなさない引数が欠落していると通知します

プログラムがコンパイルしてからクラッシュするかどうか、コンパイルではなくクラッシュするかどうか、コンパイラーがクラッシュするかどうか、どのタイプの引数が欠落しているかを明確に述べる必要があります。

あなたの言いたいことを推測すると、問題は、transformテンプレートが最後の引数に制限を設けていないため、コンパイラはどのオーバーロード (特殊化) をreciprocal変換テンプレートに渡す必要があるかを判断できないことです。必要なものを手動で指定できます。

transform(vec.begin(), vec.end(), vec.begin(), &reciprocal<int>);

または、変換を伴うテンプレートの使用を禁止できますか?

これは、いくつかの一般的な誤解を示しているという点で、それ自体が興味深い点です。Atemplateは、他の要素が作成される青写真です。この場合、コンパイラがテンプレート引数を置き換えることによってさまざまな関数を生成する単なる青写真である関数テンプレートがあります。関数が必要なコンテキストでは、特殊化(つまり、その関数テンプレートから生成された関数) を使用できますが、関数テンプレートは使用できません。

テンプレートの名前を使用して具体的な特殊化を参照できるコンテキストでは、これは少し混乱します。つまり、クラス テンプレート定義 (またはそのメンバーの定義) 内で、テンプレートの名前を使用して特殊化を参照できます。関数テンプレートの場合、テンプレートの名前を使用して、コンパイラがこれらの特殊化の 1 つを除いてすべてを破棄できるコンテキストで、関数テンプレートの可能なすべての特殊化を参照できます。次に例を示します。

int call(int (*ptr)(int)) { return ptr(5); }
call(reciprocal);       // [1]

[1] では、関数 templateの可能なすべてreciprocalの特殊化を参照しますが、これらの特殊化の 1 つ (すなわち) のみが の引数として使用できるため、この特定の使用が許可されています。reciprocal<int>call

ただし、これらは例外です。要点は、クラス テンプレートまたは関数テンプレートクラスまたは関数ではなく、コンパイラによってクラスおよび関数を作成できるジェネレータであるということです。

于 2013-07-18T16:09:48.073 に答える