开发者

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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜