为什么模板不隐式实例化为const或引用类型?

Why do templates not implicitly instantiate to const or reference types?

本文关键字:const 引用类型 实例化 为什么      更新时间:2023-10-16

考虑以下带有显式特化的函数模板。

template<typename T>
void f(T);
template<>
void f<int>(int i) { std::cout << "f() chose intn"; ++i; }
template<>
void f<const int&>(const int&) { std::cout << "f() chose const int&n"; }

第一个专门化可以隐式实例化。第二个不能,即使第一个专门化不存在。这与函数重载的规则不同,函数使用intconst int&可以正常工作(链接示例中使用g())。

具有int专门化可用的示例。作品。

http://coliru.stacked-crooked.com/a/1680748749f36631

只有const int&专门化可用的示例。编译但链接失败。

http://coliru.stacked-crooked.com/a/ab8b068d3f807837

为什么模板类型演绎是这样工作的?为什么选择这样工作?另一种方法是让模板类型演绎的行为类似于函数重载。

我的理解是,对于重载函数,编译器已经知道所有可用的选项,但是对于模板,编译器必须首先决定要查找什么,然后看看它是否可以实例化。如果是这种情况,那么要求编译器搜索类型的合格变体是不合理的要求吗?

考虑没有显式特化的情况:

template <typename T>
void f(T x)
{
    T y = 42 + x;
    std::cout << y;
}
int main()
{
    int n = 1337;
    f(n);
}

模板实参演绎永远不会演绎引用类型,因为替代方法是总是演绎引用类型。如果是这样,上面对f(n)的调用将调用f<int&>,这将使T y = 42 + x;成为病态的。

选择专门化发生在演绎完成后。

第一个专门化可以隐式实例化。第二个不能,即使第一个专门化不存在

你不能让f<int>缺席,你在这里声明:

template<typename T>
void f(T);