13

何年にもわたって C++ でコーディングした後、今日、簡単な質問をされましたが、実際にその答えを見つけることができなかったので、ここにいます。

なぜこのエラーが発生しているのか疑問に思うだけでなく、テンプレート関数だけを変更して (関数を変更せずに)以下のエラーを解決する方法を知りたいです。main()

template <class T>
T Add(T first, T second)
{
    return first + second;
}

int main()
{
    auto sample_1 = Add(1, 2); // Works
    auto sample_2 = Add(1.f, 2.f); // Works
    auto sample_3 = Add(1.f, 2); // Error: no instance matches the argument types: (double, int)
    return 0;
}
4

6 に答える 6

16

なぜこのエラーが発生するのか疑問に思うだけでなく、

を呼び出すAdd(1.f, 2)場合、最初の引数の型はfloatで、2 番目の引数の型はintです。

コンパイラは、最初の引数を に変換するかint、2 番目の引数をに変換する必要がありfloatます。どちらも変換が必要になるため、どちらも同じように適切な候補です。どちらか一方を優先することはできません。

テンプレート関数だけを変更して以下のエラーを解決する方法を知りたい

関数テンプレートを次のように変更できます。

template <class T1, class T2>
auto Add(T1 first, T2 second)
{
    return first + second;
}

または(@PiotrSkotnickiに感謝):

template <class T>
T Add(T first, decltype(first) second)
{
    return first + second;
}

この場合、 の型はsecond、関数に渡される引数から推測されません。の型はfirst最初の引数から推定され、 の型はsecondの型と同じに強制されますfirst

Add(1.2f, 2);  // The first argument is deduced to be float
               // The second argument is forced to be float.

Add(2, 1.2f);  // The first argument is deduced to be int
               // The second argument is forced to be int.
于 2015-10-02T19:35:32.583 に答える
9

ただ行う:

template <class T1, class T2>
auto Add(T1 first, T2 second)
{
    return first + second;
}

unique と同様に、 once as 、 once as ...Tと推定されます。intdouble

于 2015-10-02T19:34:42.927 に答える
4

あなたが持っているとき

template <class T>
T Add(T first, T second)

のタイプfirstsecond同じである必要があります。2 つの異なる型を取得する場合は、2 番目のテンプレート パラメーターを追加できます。

template <class T1, class T2>
auto Add(T1 first, T2 second)

または C++11 の場合

template <class T1, class T2>
auto Add(T1 first, T2 second) -> decltype(first + second)
于 2015-10-02T19:34:58.930 に答える
3

コンパイラは、署名に一致する関数を作成するために使用できるテンプレートの種類を推測しようとしています。パラメータが異なる型であるため、そうすることができません。

タイプを明示的に指定できます。

auto sample_3 = Add<float>(1.f, 2);

しかし、あなたはそれをしたくないと言います。

関数を変更して、2 つのテンプレート タイプを取得できます。

template <class T1, class T2>
T1 Add(T1 first, T2 second)
{
    T1 p;
    p = first + second;
    return p;
}

しかしここで、どの型を返すかを仮定する必要があります。

戻り値の型として使用しようとしたことはありませんautoが、どうやら機能するようです: http://ideone.com/1qO95w

template <class T1, class T2>
auto Add(T1 first, T2 second)
{
    auto p = first + second;
    return p;
}
于 2015-10-02T19:36:18.190 に答える
2

Why write your own function when the standard already provided them?

In c++11, you can use:

#include <functional>
int main()
{
    auto sample_1 = std::plus<float> () ( 1, 2 ); // Works
    auto sample_2 = std::plus<float> () ( 1.f, 2.f ); // Works
    auto sample_3 = std::plus<float> () ( 1.f, 2 ); // Works
    return 0;
}

In c++14:

#include <functional>
int main()
{
    auto sample_1 = std::plus<> () ( 1, 2 ); // Works
    auto sample_2 = std::plus<> () ( 1.f, 2.f ); // Works
    auto sample_3 = std::plus<> () ( 1.f, 2 ); // Works
    return 0;
}
于 2015-10-03T00:13:44.073 に答える
1

テンプレート関数だけを変更して以下のエラーを解決する方法を知りたい

そのように:

template <class T1, class T2>
T1 Add(T1 first, T2 second)
{
    T1 p;
    p = first + second;
    return p;
}

int main()
{
    auto sample_1 = Add(1, 2);
    auto sample_2 = Add(1.f, 2.f);
    auto sample_3 = Add(1.f, 2);
    return 0;
}
于 2015-10-02T19:34:49.043 に答える