【问题标题】:Move a vector<T*> to vector<const T*>将 vector<T*> 移动到 vector<const T*>
【发布时间】:2018-03-05 11:26:23
【问题描述】:

是否可以将vector&lt;T*&gt; 移动到vector&lt;const T*&gt; 而不复制它并且不依赖reinterpret_cast&lt;&gt;?即

vector<int*> get() {
   return ...;
}

vector<const int*> getConst() {
   return whatgoeshere(get());
}

【问题讨论】:

  • 应该不会……
  • 这是人们开始问你为什么要这样做的地方?这听起来像xy problem
  • propagate_const?
  • 如果您按价值返回,为什么还要担心副本?
  • @StoryTeller:看起来很有趣,但我看不出它到底是如何应用在这里的。并且重新复制,很容易做到这一点:auto tmp = get(); return {tmp.begin(), tmp.end()};,但这会产生额外的不必要的复制。

标签: c++ vector constants


【解决方案1】:

我将从另一个角度来攻击它。并解决可能的设计问题。您没有指定 ... 中的内容,但假设 get 填充了一个向量然后返回它,我认为的解决方案是提升在 both 之外进行填充的代码功能。

template<typename Int>
void do_get(std::vector<Int*>& v) {
  // Populate v
}

auto get() {
   std::vector<int*> ret;
   do_get(ret);
   return ret;
}

auto getConst() {
   std::vector<const int*> ret;
   do_get(ret);
   return ret;
}

填充逻辑的一个真实来源。虽然两个原始功能相同,但可以忽略不计。此外,在一个理智的实现中,它不会做任何多余的副本,因为 RVO 非常棒。

【讨论】:

  • @LightnessRacesinOrbit - 我必须承认在第一次阅读您的答案时没有推断出这一点。而且我觉得任何时候 OP 都会从下面拉下地毯。我讨厌代码中的...
  • 有A,需要B。无法将A转换为B。解决方案:以B而不是A开头,或者以A而不是B结尾。你已经展示了前者;)
  • @LightnessRacesinOrbit - 嗯,当你拼出来时很明显:p
  • A B C D E F G... :D
  • 这是一个非常聪明的解决方案,谢谢。从技术上讲,它不能回答问题,但在我的情况下,您对 ... 的看法是正确的。
【解决方案2】:

没有。

虽然T* 可以简单地转换为const T*,但T* 的容器与const T* 的容器没有“关联”,因此根本没有功能可以满足您的要求。

还要考虑这样的功能可能会假设将int** 分配给const int**,这是不允许的(当程序员打算将此分配作为交换操作的一部分时,没有提供特殊情况,如据我所知)。

此外,reinterpret_cast 只会破解这些事实,给您的程序带来未定义的行为。

你被三个选项困住了:

  • 复制向量 (O(n))
  • 首先让你拥有你想要的容器 (O(∞))
  • 让它完全不需要新的容器类型 (O(?))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 2020-10-17
    • 2018-02-02
    • 1970-01-01
    • 2021-06-02
    • 2019-10-20
    • 2017-07-18
    相关资源
    最近更新 更多