代码之家  ›  专栏  ›  技术社区  ›  starswap

C++如何在不明确的模板之间进行选择?

  •  1
  • starswap  · 技术社区  · 1 年前

    我在Effective Modern C++中读到了关于模板类型推导的文章,我想我理解编译器如何确定模板是否匹配,以及推导出的类型应该是什么,但我不理解编译器如何在匹配的重载之间进行选择。

    考虑这个例子:

    #include <iostream>
    
    template <typename T>
    void hello(T& a) {
        std::cout << "Hello World 1" << std::endl;
    }
    
    template <typename T>
    void hello(const T& a) {
        std::cout << "Hello World 2" << std::endl;
    }
    
    int main() {
        int x = 6;
        const int y = 5;
        int& z = x;
    
        hello(x);
        hello(y);
        hello(z);
    }
    

    这会产生以下输出:

    Hello World 1
    Hello World 2
    Hello World 1
    

    直观地,我可以看到编译器选择了 const 输入值为时过载 const 这似乎有道理,但我原以为它会因为歧义而出错。特别是,如果我们删除的任一版本 hello 函数,代码仍然编译,所有调用都使用另一个。这意味着编译器可以通过某种方式选择在这种情况下更可取的模板,以避免歧义。

    我发现这个解释很好 What is the partial ordering procedure in template deduction ,但我对将其应用于这种情况感到困惑。特别是遵循该问题答案中概述的过程意味着模板本身有一个排序,它决定了哪一个“更专业”,因此无论输入参数如何,都将始终受到青睐。这与以下事实不一致:在我的示例中,编译器根据输入类型做出了两种不同的选择。

    1 回复  |  直到 1 年前
        1
  •  2
  •   Swift - Friday Pie    1 年前

    第一个模板的功能 void(int&) 可以与匹配 void(const int&) ,但不是相反,因此它更专业 hello(x) 这是我最喜欢的选择。

    出于同样的原因 void(const int&) 是的唯一匹配项 hello(y) .

    电话 hello(z) 与没有什么不同 你好(x) 在这种情况下。引用将被“丢弃”。