5

这里有两个模板函数,它们的不同之处仅在于它们的模板参数。其余参数完全相同。

    template<int module>
    void template_const(int &a,int & b){
            a = a & module;
            b = b % module;
    }

    template<bool x>
    void template_const(int &a,int & b){
            int w;
            if (x){
                    w = 123;
            }
            else w = 512;
            a = a & w;
            b = b % w;
    }

当我尝试这样称呼他们时

template_const<true>(a,b)

或者

template_const<123>(a,b)

编译器告诉我调用不明确。如何调用这两个函数?

4

2 回答 2

6

正如@jogojapan 指出的那样,问题在于编译器无法对这两个函数进行排序,即没有一个比另一个更专业。如第 14.5.6.2 节所述,当对重载函数模板的调用不明确时,编译器会使用各种重载之间的偏序来选择最专用的一个。

为了对重载进行排序,编译器对它们中的每一个进行转换并执行模板参数推导,以查看一个是否比另一个更专业(此答案末尾有一个简短的解释)。在您的情况下,这两个重载是等效的(或不可比较的):template<int> void template_const(int &,int &)不比 更专业template<bool> void template_const(int &, int &),反之亦然。

因此,编译器无法选择其中一个,从而产生ambiguous call错误。


如果您可以明确指定要传递的参数的类型,则可以使用部分模板特化,如下所示:

template<typename T, T param>
struct template_const_impl;

template <int module>
struct template_const_impl<int, module>
{
    static void apply(int &a, int &b)
    {
        a = a & module;
        b = b % module;
    }
};

template<bool x>
struct template_const_impl<bool, x>
{
    static void apply(int &a, int &b)
    {
        const int w = x ? 123 : 512;
        a = a & w;
        b = b % w;
    }
};

template <typename T, T param>
void template_const(int &a, int &b)
{
    return template_const_impl<T, param>::apply(a, b);
}

int main()
{
    int i = 512, j = 256;
    template_const<int, 123>(i, j);
    template_const<bool, true>(i, j);
}

这并不理想,但它认为没有更清洁的解决方案,除非您可以使用 C++11 并且愿意依赖一些宏,在这种情况下您可以稍微简化调用代码(来自@Nawaz 的想法在这个答案中):

#define TEMPLATE_CONST(x) template_const<decltype(x), x>

int main()
{
    int i = 512, j = 256;
    TEMPLATE_CONST(123)(i, j);
    TEMPLATE_CONST(true)(i, j);
}
于 2013-06-26T07:39:47.537 回答
0

我不认为它会像这样工作。您有具有相同参数类型的重载。可能你最终不得不给他们不同的名字,并在你尝试的时候给他们打电话。

于 2013-06-26T07:22:39.170 回答