I have following demonstration code:
template <int i, typename T, typename U>
T func(const U &t){return i * t;}
template <int i, typename T>
T func(const T &t){return 2 * i * t;}
int main()
{
return func<1, int>(1);
}
Which is a boiled down version of my real code, so it seems useless but should suffice to show the problem:
In function ‘int main()’:
11:23: error: call of overloaded ‘func(int)’ is ambiguous
11:23: note: candidates are:
2:3: note: T func(const U&) [with int i = 1, T = int, U = int]
5:3: note: T func(const T&) [with int i = 1, T = int]
So it is clear that the automatic type inference (for template parameter U) interferes with my interests of picking the right version of the template function (which is the one that has only 2 parametrs)
I need both versions to have a basic and a specialized template, that do things a little different.
So the question is: Is there any possibility to tell the compiler not to infer the type automatically at this point (for example by somehow saying: Take the template that has only 2 parameters)?
You can pass an initializer list, which effectively disables deduction (but causes list-initialization of parameters which in this case of int
has the same effect though):
template <int i, typename T, typename U>
T func(const U &t){return i * t;}
template <int i, typename T>
T func(const T &t){return 2 * i * t;}
int main()
{
return func<1, int>({1});
}
But in your case, if you call func<N>(...)
you seem to want to call the second one, and if you call func<N, T>(...)
you always seem to want to call the second one too, and only for func<N, T, U>(...)
you want to call the first one, so you can always disable deduction for U
by making the parameter a nondeduced context for it
template <int i, typename T, typename U>
T func(typename std::common_type<const U &t>::type t){return i * t;}
template <int i, typename T>
T func(const T &t){return 2 * i * t;}
int main()
{
return func<1, int>({1});
}