使用const引用的函数模板重载决策

时间:2016-09-01 11:00:13

标签: c++ templates overload-resolution

我试图在以下情况下理解重载决策规则:

template<typename T>
void f(const T& x) { 
    std::cout << __PRETTY_FUNCTION__ << std::endl; //-
}

template<typename T>
void f(T& x) { // <> Überladung Variante 2
    std::cout << __PRETTY_FUNCTION__ << std::endl; //-
}

int main()
{
    int e1 = 0;
    f(e1);

    const int e2 = 0;
    f(e2); 
}

输出结果为:

void f(T &) [T = int]
void f(const T &) [T = int]

据我所知,在第一次调用f(e1)时会导致可行的功能

void f(const int&)
void f(int&)

从中选择第一个,因为不必删除const限定。

第二次调用f(e2)会导致类型扣除/可行功能

void f(const int&); // T -> int from first template overload 
void f(const int&); // T -> const int from second overload

并且输出显示选择了第一个重载。

但为什么?

1 个答案:

答案 0 :(得分:3)

使用引用执行类型推导时,不会删除const - ness(更具体地说是CV-ness)。因此,在您的情况下,编译器有2个重载可供选择:

void f(const T &)
void f(T &)
然后,编译器执行&#34;模式匹配&#34;为const int e2 = 0;参数选择重载时。第一个const重载是更好的匹配(更专业),因为第二个需要将T推导为const int,这会增加一些内容(即const - ness)。

模板类型推导的规则并不是非常简单,所以如果你想了解有关模板的所有细节,我强烈推荐这本书

David Vandevoorde和Nicolai M. Josuttis的

C++ Templates: The Complete Guide

它是C ++之前的11,但它告诉你你可以想到的一切

PS:您必须区分实例化模板类型推导。首先进行类型推导,然后进行实例化。所以在你的情况下,你没有像你最初想到的那样有两个模糊的实例。