Reputation: 3737
After years of coding in c++, today I was asked a simple question, but indeed I couldn't find its answer and so here I am guys.
Besides wondering why this error is happening, I want to know how I can solve below error by modifying just the template function (without changing the main()
function)
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;
}
Upvotes: 13
Views: 2134
Reputation: 3319
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;
}
Upvotes: 2
Reputation: 308392
The compiler is trying to deduce the template type that it can use to create a function that matches the signature. Since the parameters are different types, it's unable to do so.
You could specify the type explicitly:
auto sample_3 = Add<float>(1.f, 2);
But you say you don't want to do that.
You can change the function to take two template types:
template <class T1, class T2>
T1 Add(T1 first, T2 second)
{
T1 p;
p = first + second;
return p;
}
But now you'll have to make an assumption about which type to return.
I've never tried to use auto
as the return type, but apparently it works: http://ideone.com/1qO95w
template <class T1, class T2>
auto Add(T1 first, T2 second)
{
auto p = first + second;
return p;
}
Upvotes: 3
Reputation: 206667
Besides wondering why this error is happening,
When you call Add(1.f, 2)
, the first argument type is float
and the second argument type is int
.
The compiler has to convert either the first argument to an int
or the second argument to a float
. Since both of them will require a conversion, they are equally good candidates. One cannot be preferred over the other.
I want to know how I can solve below error by modifying just the template function
You can change the function template to:
template <class T1, class T2>
auto Add(T1 first, T2 second)
{
return first + second;
}
or to (thanks @PiotrSkotnicki):
template <class T>
T Add(T first, decltype(first) second)
{
return first + second;
}
In this case, the type of second
is not deduced from the argument being passed to the function. Type of first
is deduced from the first argument and the type of second
is forced to be the same as the type of 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.
Upvotes: 16
Reputation: 180935
When you have
template <class T>
T Add(T first, T second)
the type of first
and second
need to be the same. If you want to take two different types then you can add a second template parameter
template <class T1, class T2>
auto Add(T1 first, T2 second)
or for C++11
template <class T1, class T2>
auto Add(T1 first, T2 second) -> decltype(first + second)
Upvotes: 4
Reputation: 21514
I want to know how I can solve below error by modifying just the template function
Like that:
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;
}
Upvotes: 1
Reputation: 217810
Just do:
template <class T1, class T2>
auto Add(T1 first, T2 second)
{
return first + second;
}
As with unique T
, it is deduced once as int
, once as double
...
Upvotes: 9