如何区分具有非类型参数的模板的重载? [英] How can I distinguish overloads of templates with non-type parameters?

查看:107
本文介绍了如何区分具有非类型参数的模板的重载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里有两个模板函数,它们的区别仅在于它们的模板参数。其余的参数是完全一样的。

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

模板< 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)


$ b b

  template_const< 123>(a,b)
/ pre>

编译器告诉我调用是不明确的。

解决方案

正如@jogojapan指出的,问题是编译器不能命令这两个函数,即没有一个比另一个更专门化。如第14.5.6.2节所述,当对重载函数模板的调用不明确时,编译器使用各种重载之间的部分顺序来选择最特殊的。



为了排序重载,编译器转换每一个,并执行模板参数演绎,看看是否比另一个更专业(在此回答)。在你的情况下,这两个重载是等价的(或不可比较): template< int> void template_const(int&,int&)不比 template< bool>



因此,编译器不能选择一个在另一个之上,因此,因此产生模糊调用错误。






通过明确指定要传递的参数的类型,您可以使用部分模板专门化如下:

  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&模块;
b = b%module;
}
};

template< bool x>
struct template_const_impl< bool,x>
{
static void apply(int& a,int& b)
{
const int w = 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);
}


Here are two template functions, that differ only in their template parameters. The rest of the parameters are exactly the same.

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

When I try to call them like this

template_const<true>(a,b)

or

template_const<123>(a,b)

the compiler tells me that the call is ambiguous. How can I call these two functions?

解决方案

As @jogojapan pointed out, the problem is that the compiler cannot order these two functions, i.e. there is not one that is more specialized than the other. As explained in §14.5.6.2, when a call to an overloaded function template is ambiguous, the compiler uses a partial ordering between the various overloads to select the most specialized one.

To order the overloads, the compiler transforms each one of them and performs template argument deduction to see if one is more specialized than another one (there is a short explanation at the end of this answer). In your case, the two overloads are equivalent (or not comparable): template<int> void template_const(int &,int &) is not more specialized than template<bool> void template_const(int &, int &), and vice-versa.

Therefore, the compiler cannot select one over the other, hence generating an ambiguous call error.


If you are ok with explicitely specifying the type of the parameter you want to pass, you can use partial template specialization as follow:

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

This is not ideal, but it don't think there is a cleaner solution unless you can use C++11 and are willing to rely on some macros, in which case you can simplify the calling code a bit (idea taken from @Nawaz in this answer):

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

这篇关于如何区分具有非类型参数的模板的重载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆