【问题标题】:deduction guides and injected class names推导指南和注入的类名
【发布时间】:2018-12-11 10:24:34
【问题描述】:
template <typename T>
struct X
{
    template <typename Iter>
    X(Iter a, Iter b) {}

    template <typename Iter>
    auto f(Iter a, Iter b)
    {
        return X(a, b);
    }
};

“C++模板,完整指南”第二版中,有前面的例子,关于隐式演绎指南的字幕注入类名。作者提到对于注入的类名禁用类参数推导,因为由于隐式推导指南, f 的返回类型将为X&lt;Iter&gt;。但我相信模板构造函数的隐式推导指南会像下面的那样。

  template <typename T, typename Iter>
  X(Iter a, Iter b) -> X<T>;

我的问题是如何在这种情况下推导出类模板参数类型 TIter 是两种不同的类型,参数类型仅依赖于 Iter。此外,即使 T 可以以某种方式推断出来,TIter 是独立的,因此从参数中推断出 Iter 不应该意味着 X 具有类型 X&lt;Iter&gt; 对吗?这是书上的文字有什么错误,还是推理指南看起来和我想的不一样?

【问题讨论】:

    标签: c++ c++17 type-deduction


    【解决方案1】:

    你是对的。隐式生成的推导指南确实看起来像您编写的那个。并且模板参数推导永远无法从中推导出T。这确实不会造成问题。问题在于用户提供的扣除指南。像这样:

    template <typename Iter>
    X(Iter a, Iter b) -> X<typename Iter::value_type>;
    

    Which are often added to allow class template argument deduction from iterators。如果注入的类名没有抑制参数推导,那可能会造成严重破坏。作者可能忽略了添加演绎指南来证明问题的必要性。

    以下是问题的说明:

    auto v = std::vector<int>{1, 2};
    auto x1 = X<float>(begin(v), end(v));
    auto x2 = x1.f(begin(v), begin(v));
    

    x2 的类型是什么?如果我们阅读类模板定义,我们希望它是 X&lt;float&gt;,就像在 C++14 中一样,但是如果没有关闭类模板参数推导并且我们添加我们的推导指南,我们将得到 @987654327 @!

    想象一下现有的代码库,在迁移到 C++17 后类型突然发生了变化。那会很糟糕。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多