【问题标题】:Enabling implicit conversion from `vector<const T>&` to `const vector<T>&`启用从 `vector<const T>&` 到 `const vector<T>&` 的隐式转换
【发布时间】:2020-10-17 21:55:05
【问题描述】:

假设我们定义了一个类template&lt;typename T&gt; class vector,它的行为类似于std::vector,只是我们能够改变它的类定义。

还假设我们有一个函数f(const vector&lt;T&gt;&amp;)

我们如何启用隐式转换,允许我们将vector&lt;const T&gt;&amp; 传递到f


我认为这种隐式转换是明智的,因为我相信const vector&lt;T&gt;&amp; 施加的限制是vector&lt;const T&gt;&amp; 施加的限制的超集。但任何可能具有启发性的指导都将不胜感激。

【问题讨论】:

  • 我假设您也希望相反的转换起作用?
  • @HolyBlackCat 不,因为vector 可以通过比覆盖/修改单个元素更多的方式进行修改。所以我认为const vector&lt;T&gt;vector&lt;const T&gt; 更受限制。
  • std::vector&lt;const T&gt; 是一个非常有限的类型。在 C++11 之前它是格式错误的,之后就不能添加元素了

标签: c++ type-conversion c++14 constants implicit-conversion


【解决方案1】:

假设f 确实是一些具体T函数,而不是函数模板(即template&lt;typename T&gt; f(vector&lt;T&gt; const&amp;)),那么vector&lt;T&gt; 中的以下运算符应该可以工作:

template<typename U = T, typename = std::enable_if_t<std::is_const<U>{}>>
operator vector<std::remove_const_t<U>>() const {
    // ...
}

Online Demo

但是,f 不能是一个独立的函数模板,因为它的T 将被简单地推导出为它自己const,并且不会发生任何转换。重载可以解决这个问题,但会很丑。

注意这大概只是复制原始vector 中的元素;返回一个 vector&lt;T&gt; const&amp; 以某种方式对原始 vector&lt;T const&gt; 的内部进行别名是一项截然不同的任务,因为它会涉及额外的生命周期管理状态和/或有问题的合法类型别名。

【讨论】:

  • 鉴于我们正在实现vector&lt;T&gt;,我们可以声明转换后的数组是原始数组的视图,因此仅有效直到它的源向量改变。我认为这将解决生命周期管理问题。
  • @Toby :这都是非常假设的......这是想象中的vector 使用标准库的分配器模型吗?如果是这样,删除constness 就是在玩火 UB 明智的;如果没有,那么,为了方便,我们可以改变各种的东西。 ;-]
  • 我认为这是安全的,因为我们从不暴露非 const T&amp;。但是看起来很难硬塞到单个 vector 类而不是单独的视图类中。正如你所说,目前这完全是推测性的。我很高兴不再去想它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-20
  • 2021-06-02
  • 1970-01-01
  • 2017-07-18
  • 1970-01-01
  • 2016-11-11
相关资源
最近更新 更多