C++ Partial Ordering Fails with 2 Template Parameters
So given the following template functions with partial specialization
template<typename T>
void foo(vector<T> &in) {
cout << "vector" << endl;
}
template<typename T>
void foo(T &in) {
cout << "scalar" << endl;
}
int main(int arc, char *argv[]) {
vector<double> a;
double b;
foo(a);
foo(b);
return 0;
}
I have no problem compiling with g++ 3.4.6 and get the expected output:
vector
scalar
Now, if I add a second template parameter:
template<class U, typename T>
void foo2(vector<T> &in) {
U a;
cout << "vector" << endl;
}
template<class U, typename T>
void foo2(T &in) {
U a;
cout << "scalar" << endl;
}
and call it with the following:
int main(int arc, char *argv[]) {
vector<double> a;
double b;
foo2<double>(a);
foo2<double>(b);
return 0;
}
When I try to compile it GCC 3.4.6 gives me an ambiguous ov开发者_开发技巧erload error.
error: call of overloaded `foo2(std::vector<double, std::allocator<double> >&)' is ambiguous
note: candidates are: void foo2(std::vector<T, std::allocator<_T2> >&) [with U = double, T = double]
note: void foo2(T&) [with U = double, T = std::vector<double, std::allocator<double> >]
I fail to see how the second template parameter now makes the overload ambiguous. As far as I can tell the vector version should still be more specialized. Is this just a bug in 3.4? Is there a workaround?
For the record the code works in gcc 4.1 without issue. Unfortunately some of our tools are still tied to 3.4 so that upgrading isn't the solution.
Thanks.
This seems to be related to this defect which is fixed in the latest version of the compiler. Workarounds are to explicitly set all arguments of the template or to use functor instead:
template<typename U>
struct foo2 {
template<typename T>
void operator()( std::vector<T> &in ) {
U a;
cout << "vector" << endl;
}
template<typename T>
void operator()( T& in ) {
U a;
cout << "scalar" << endl;
}
};
int main(int arc, char *argv[]) {
vector<double> a;
double b;
foo2<double>()(a);
foo2<double>()(b);
return 0;
}
精彩评论