【问题标题】:Why parameter deduction doesn't work in this template template parameter为什么在这个模板模板参数中参数推导不起作用
【发布时间】:2019-06-18 11:17:52
【问题描述】:

我有以下模板函数,它以模板模板参数为参数。

template<typename T, 
         template <typename... ELEM> class CONTAINER = std::vector>
void merge(typename CONTAINER<T>::iterator it )
{
   std::cout << *it << std::endl;
}

下面的代码使用了这个代码。

std::vector<int> vector1{1,2,3};
merge<int>(begin(vector1));

它按预期工作,但是当我使用时

merge(begin(vector1));

无法推断T的类型。

我认为它可以从std::vector&lt;int&gt;::iterator it; 推断类型为int

为什么编译器不能推断出类型?

【问题讨论】:

  • 建议:搜索“非推断上下文”
  • 这个问题是在 3 天前提出的(并已回答):stackoverflow.com/questions/56626007/…
  • 他正在尝试完全相同的事情 - 尝试根据 T::iterator 类型推断类型 T。这在函数和类中都是不可能的。
  • 请注意,您也不是在推断CONTAINER,而是使用默认值。 std::set&lt;int&gt; set1 {1, 2, 3}; merge&lt;int&gt;(begin(set1));fails
  • 如果只需要从decltype(it)获取int,那么使用std::iterator_traits&lt;&gt;::value_type。例如。 template &lt;typename Iterator, typename Value = std::iterator_traits&lt;Iterator&gt;::value_type&gt; void merge(Iterator it)

标签: c++ templates c++14 template-argument-deduction template-templates


【解决方案1】:

我认为它可以从 std::vector&lt;int&gt;::iterator it; 推断类型为 int。

为什么编译器不能推断出类型?

没有。

编译器不能:查找“非推断上下文”以获取更多信息。

并且期望扣除是不合理的。

假设一个类如下

template <typename T>
struct foo
 { using type = int; };

type 的类型为 always intT 类型是什么。

假设一个函数如下

template <typename T>
void bar (typename foo<T>::type i)
 { }

接收int 值(typename foo&lt;T&gt;::type 始终为int)。

应该从下面的调用中推断出哪个T 类型?

bar(0);

【讨论】:

  • 我想在 foo 中“使用 type = T”。所以0是int,所以T是int。编译器是不可能的吗?
  • @user150497 关键是有无数个Ts,这样foo&lt;T&gt;::type 就是int。语言被定义为不必在它们之间做出选择。
  • @user150497 - 问题不是那是不可能的。问题(恕我直言,显然)是不合理的。在您的特定情况下,内部类型允许推断模板参数。一般来说是不可能的,并且添加一条规则(无论如何都是有问题的)来推断特定情况下的类型将迫使编译器进行大量额外的工作来查看所有可能的组合并仅在单个模板匹配时接受代码。
猜你喜欢
  • 2010-11-19
  • 2015-10-06
  • 2011-08-28
  • 2021-12-06
  • 1970-01-01
  • 2017-02-08
  • 1970-01-01
相关资源
最近更新 更多