因此,给出以下带有部分特化的模板功能

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

我在使用g++ 3.4.6编译时没有问题,并获得了预期的输出:
vector
scalar

现在,如果我添加第二个模板参数:
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;
}

并使用以下命令调用它:
int main(int arc, char *argv[]) {
    vector<double> a;
    double b;

    foo2<double>(a);
    foo2<double>(b);
    return 0;
}

当我尝试编译它时,GCC 3.4.6给了我一个模棱两可的过载错误。
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> >]

我看不到第二个模板参数现在如何使重载模棱两可。据我所知, vector 版本应该仍然更加专业。这仅仅是3.4中的错误吗?有解决方法吗?

为了记录,该代码在gcc 4.1中正常运行。不幸的是,我们的某些工具仍与3.4绑定(bind),因此升级不是解决方案。

谢谢。

最佳答案

这似乎与this defect有关,后者在最新版本的编译器中为fixed。解决方法是显式设置模板的所有参数,或者改用functor:

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

07-28 01:33
查看更多