重複の可能性:
戻り値の型に基づく関数のテンプレート推定?
C++ テンプレートがどのように機能するかを理解しようとしています。triple
例として、 STL のように動作するが 3 つの項目を持つ単純なデータ構造を書きたいとしpair
ます。もちろん、テンプレートを使用して実装したいと考えています。そして、私は自分の観点から奇妙な行動に直面しています。
まず、実際の例があります。動作する C++ コードは次のとおりです。
template<typename T1, typename T2>
T1 getSum(T1 a1, T2 a2) {
return a1 + a2;
}
int main(int argc, int *argv[]) {
long l1 = 1, l2 = 0, l3 = 0, l4 =0;
short s1 = 2, s2 = 0, s3 = 0, s4 = 0;
l2 = getSum(l1, s1);
l3 = getSum(s1, l1);
l4 = getSum(1, 2);
s2 = getSum(l1, s1);
s3 = getSum(s1, l1);
s4 = getSum(1, 2);
cout << l2 << " " << l3 << " " << l4 << endl;
cout << s2 << " " << s3 << " " << s4 << endl;
return 0;
}
このプログラムの結果は、3 3 3
それぞれを含む 2 行になります。getSum
引数のさまざまな組み合わせで関数を呼び出すので(long, short)
、戻り値は毎回変数と変数の両方に割り当てられるため、コンパイラーは戻り値によって適切な変換または型の推測を行う方法を知っていると仮定し(short, long)
ます(integer literal, integer literal)
(long
整数リテラルの場合)。毎回。short
triple
ここで、単純な実装に戻ります。私はすべてをほぼ同じ方法で行いますが(私には思えますが)、変換エラーが発生します。これが私の言いたいことです。私のコードは次のようになります。
template <typename T1, typename T2, typename T3>
struct triple {
T1 first;
T2 second;
T3 third;
};
template <typename T1, typename T2, typename T3>
triple<T1, T2, T3> mt(T1 f, T2 s, T3 t) {
triple<T1, T2, T3> tr;
tr.first = f;
tr.second = s;
tr.third = t;
return tr;
};
int main(int argc, char* argv[]) {
triple<char, char, unsigned short> t = mt(0, 0, 65000);
cout << t.first << " " << t.second << " " << t.third << endl;
return 0;
}
ただし、コンパイルしようとすると、次のエラーが発生します。
22: error: conversion from 'triple<int, int, int>' to non-scalar type
'triple<char, char, short unsigned int>' requested
(22 行目はmain
関数の最初の行です)。
triple
前述の 2 つの の間の変換がコンパイラの仕事ではないことは驚くことではありません。しかし、関数の結果として取得したいので、テンプレート引数を, ,として決定する必要があることをコンパイラが決定できないことは、私にとって驚きです。triple<char, char, short unsigned int>
mt
T1 == char
T2 == char
T3 == unsigned short
そして、物事がこのように機能するようになったので、関数がどのようにmake_pair
機能するかについて混乱しています。そのコードは私のものと非常によく似ています (繰り返しますが、私にはそう思われます)。
だから、私の質問は:私のコードと実際のコードの本質的な違いを明確にしてください:)