Hi all,
I am trying to specialize some (non-trivial) function templates, but I
am getting a lot of unexpected compile errors. These are functions with
a template parameter that can not be inferred by parameters types and
needs to be explicitly set at the function call. Can someone give me
some light? Read on for a more in-depth explanation.
Below we have a traditional partial specialization. This compiles and
works fine.
//Generic function
template
void f(T a, U b) {}
//Partial specialization
template <class U>
void f(int a, U p) {}
int main(int argc, char **argv)
{
long a, b;
int c;
f(a, b); //call the generic function
f(c, b); //call the partial specialization
}
So the code above is ok.
Now let us create a "template function", one where you can not infer one
of the template parameter just by the parameters types:
//Generic "template function"
template
void f(T a, U b) {}
int main(int argc, char **argv)
{
long a, b;
int c;
f<long>(a, b); //calls generic "template function"
f<long>(a, c); //calls generic "template function"
}
The code above also works fine. Now I want to mix both things, and this
is where the problem arises. See the code:
//Generic "template function"
template
void f(T a, U b) {}
//"template function" partial specialization
template
void f(int a, U b) {}
int main(int argc, char **argv)
{
long a, b;
int c;
f<long>(a, b); //calls generic "template function"
f<long>(c, b); //should call "template function" specialization
}
But the second function call above, surprisingly, does not compile:
g++ test2.cc
test2.cc: In function `int main(int, char**)':
test2.cc:19: error: call of overloaded `f(int&, long int&)' is ambiguous
test2.cc:8: error: candidates are: void f(T, U) [with X = long int, T =
int, U
= long int]
test2.cc:12: error: void f(int, U) [with X = long int, U
= long
int]
Same results using intel compiler:
davi@supermaquina cxx4ever $ icc -w test2.cc
test2.cc(19): error: more than one instance of overloaded function "f"
matches the argument list:
function template "f(T, U)"
function template "f(int, U)"
argument types are: (int, long)
f<long>(c, b); //should call "template function" partial
specialization
^
So, what is happening here? I do agree that this is ambiguous, but the
most specific case should be chosen, as it happens with the traditional
template specialization (which is also ambiguous until you choose the
more specific code). What makes me think that I am missing something is
that both compilers says that f() is overloaded. But it should not be.
This should be a partial specialization, not an overload. Well, that is
it. Some tips?
Thanks in advance,
Davi de Castro Reis