【问题标题】:Could an implicit template deduction guide deduce a reference type?隐式模板推导指南可以推导出引用类型吗?
【发布时间】:2017-04-20 13:35:46
【问题描述】:

在用 gcc7 测试 C++17 推导行为时,我发现这个例子失败了:

template<class T>
struct S{
  S(T&& v){}
};
int i=10;
auto v = S(i);

根据我从cpp reference 读到的内容,我认为v 应该是S&lt;int &amp;&gt; 类型。尽管如此,gcc7 并没有编译这段代码,抱怨 int&amp; 不能绑定到 int &amp;&amp;(通用引用机制失败)。

所以我的问题是:

  1. gcc7 是否应该将v 推导出为S&lt;int&amp;&gt; 类型?

  2. 工作草案标准中的自动扣除指南在哪里描述?

【问题讨论】:

  • 考虑到GCC第7版还没有发布,肯定会有bug。如果这是其中之一,我不知道。您是否尝试过在 C++17 模式下使用 GCC 6(GCC 6 支持大部分 C++17)?
  • GCC6 中没有实现推导指南。我只是想知道是cpp引用还是GCC7是对的,我自己无法判断,因为我在标准中没有找到主菜...
  • 请注意,cppreference 确实涵盖了这种情况。这是该页面上的最后一个示例。 Cubbi 和 TC 不要乱来:-)
  • 谢谢,我已经修改了文字,说这是我对cpp引用的理解,而不是直接的cpp引用......这看起来像重言式。

标签: c++ templates c++17


【解决方案1】:

[over.match.class.deduct] 中的规则是:

形成一组函数和函数模板,包括:
- 对于由模板名指定的主类模板的每个构造函数,如果模板已定义,则具有以下属性的函数模板:
- 模板参数是类模板的模板参数,后跟构造函数的模板参数(包括默认模板参数)。
- 函数参数的类型是构造函数的类型。
- 返回类型是模板名和模板参数指定的类模板特化,模板参数对应于从类模板获得的模板参数。

我们的套装包括:

template <class T> // <-- the template parameters come from the class template
S<T>               // <-- the return type is the class template specialization   
foo(T&& );         // <-- the types of the parameters are those of the constructor

我们像往常一样执行重载解析,其中涉及模板推导。 但是来自[temp.deduct.call]:

转发引用是对 cv 非限定模板参数的右值引用不代表类模板的模板参数(在类模板参数推导期间([ over.match.class.deduct]))。如果 P 是转发引用且参数是左值,则使用类型“对 A 的左值引用”代替 A 进行类型推导。

因此,这个T&amp;&amp; 不是转发引用。它是对T 的右值引用。所以对左值(在我们的例子中,S(i))的扣除失败了。 gcc 在这里拒绝你的代码是正确的。

如果希望类模板参数起到转发引用的作用,则需要添加推导指南:

template <class T> S(T&& ) -> S<T>;

【讨论】:

  • 为什么演绎指南能解决问题? T 不还是代表类模板的模板参数吗?是否有明确定义T 所属的措辞?通常,我会认为它属于类模板,就像在类模板主体之外定义的类模板的普通成员函数一样。我知道推理指南是特殊的野兽,所以我问是否有特殊的规则?
  • @JohannesSchaub-litb 在演绎指南中不是类模板的模板参数,而是演绎指南的模板参数。
  • @JohannesSchaub-litb 我知道这听起来如何。
  • 我刚刚阅读了规范,可以确认您所说的。谢谢
猜你喜欢
  • 2019-06-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-29
  • 1970-01-01
相关资源
最近更新 更多