$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Davi de Castro Reis (davicastro_at_[hidden])
Date: 2005-03-24 17:26:33
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 <class T, class U>
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<class X, class T, class U>
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<class X, class T, class U>
void f(T a, U b) {}
//"template function" partial specialization
template<class X, class U>
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_at_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<X,T,U>(T, U)"
             function template "f<X,U>(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