详解 C++ 的隐式类型转换与函数重载( 四 )


  • 不精确匹配的非模板函数void test(double)
  • 此时,由于通过模板实例化出的void test(int)是唯一精确匹配版本,故编译器将选择此版本 。
    4. test(0, 0)
    与test(0)的情况类似,由于此时不存在精确匹配的非模板函数,则编译器将选择通过模板实例化得到的版本 。此外,由于模板存在对于此调用的精确匹配的模板特化版本,所以编译器最终选择了此特化版本 。
    接下来讨论上述第二点规则,参考以下代码:
    template <typename T>void test(T) {}// 一个普适性更低的模板函数template <typename T>void test(T *) {}int main{test(0); // 调用void test(T)实例化得到的void test(int)版本test(static_cast<void *>(0)); // 调用void test(T *)实例化得到的void test(void *)版本}上述代码中,void test(T *)较之void test(T)是一个普适性更低的模板函数(类似于基于附加类型的类模板偏特化),void test(T)可接受一切类型的参数,而void test(T *)只能接受一切类型的指针参数 。
    当我们调用test(0)时,void test(T)为其唯一可行的模板函数,故编译器将选择此模板实例化得到的void test(int)版本进行调用 。而对于test(static_cast<void *>(0))调用,虽然void test(T)与void test(T *)都是其可行版本,但由于void test(T *)版本的普适性更低,故编译器将选择此版本进行实例化 。
    作者简介:樱雨楼,毕业于生物信息学专业,是一枚Python/C++/Perl开发,自称R语言黑粉,GitHub勾搭:https://github.com/yingyulou 。
    【END】

    【详解 C++ 的隐式类型转换与函数重载】


    推荐阅读