【问题标题】:Why do templates not implicitly instantiate to const or reference types?为什么模板不隐式实例化为 const 或引用类型?
【发布时间】:2014-08-17 21:51:20
【问题描述】:

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

template<typename T>
void f(T);

template<>
void f<int>(int i) { std::cout << "f() chose int\n"; ++i; }

template<>
void f<const int&>(const int&) { std::cout << "f() chose const int&\n"; }

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

提供int 的专用化示例。有效。

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

只有const int&amp; 的特化可用的示例。编译但链接失败。

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

为什么模板类型推导以这种方式工作,为什么选择以这种方式工作?另一种方法是模板类型推导表现得像函数重载。

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

【问题讨论】:

  • “不编译。”它确实编译。它不链接。无论如何,我认为你在这里得到的只是猜测。我可以自己猜测,但我认为这不会有帮助。
  • 关于编译与链接的正确性,将编辑。有时,SO 上的人们知道似乎不可能知道的事情。我充满希望。
  • 对不起,一定是看错了。
  • ? auto x = &amp;f&lt;const int&amp;&gt;; 隐式实例化第二个特化。
  • 实例化是从模板构建函数/类的过程。当您为T == int 实例化模板template&lt;class T&gt; void foo(T); 时,您将创建一个名为foo&lt;int&gt; 的函数。表达式&amp;foo&lt;int&gt; 使用函数的地址,因此该函数必须存在,因此它被实例化(如果它还不存在)。您没有像 template void foo&lt;int&gt;(int); 那样显式请求实例化,因此实例化是隐式的。

标签: c++ templates type-deduction


【解决方案1】:

考虑没有明确特化的情况:

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

int main()
{
    int n = 1337;
    f(n);
}

模板参数推导从不推导引用类型,因为替代方法是总是推导引用类型。如果是这样,上面对f(n) 的调用将调用f&lt;int&amp;&gt;,这将使T y = 42 + x; 格式错误。

选择专精会在演绎完成后发生。

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

你不能让f&lt;int&gt;缺席,你在这里声明了:

template<typename T>
void f(T);

【讨论】:

    猜你喜欢
    • 2020-07-20
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多