当前位置: 首页 > 知识库问答 >
问题:

我应该返回gsl::span而不是const std::vector

章玮
2023-03-14

我有一节课d::矢量

class demo {
public:
    //...

    const std::vector<int> & test() const {
        return iv;
    }

private:

    std::vector<int> iv;
};

我计划将成员类型更改为另一种类似于数组的容器类型,只具有足够的功能和较小的内存占用(例如std::experimental::dynarray、std::unique_ptr)

class demo {
public:
    //...

    gsl::span<const int> test() const {
        return iv;
    }

private:

    std::vector<int> iv;
};

但这破坏了使用常量向量的代码

demo d;

std::cout << (d.test().begin() == d.test().begin()) << "\n";
std::cout << (d.test().end() == d.test().end()) << "\n";

for( auto it = d.test().begin(), end = d.test().end(); it != end; ++it )
    std::cout << *it << "\n";

这将打印0 0,然后崩溃,因为测试it!=end永远不会失败。基于循环的范围当然可以工作,但是这个循环是有效的,因此也必须按照预期工作。我已经预料到,来自同一容器的同一范围的所有跨度都是相等的,所以这些跨度的迭代器是可比的(当然容器没有修改)。当然,这不是这样有一个很好的理由。

所以我的问题是,将这样一个视图返回给数组类容器的元素的最佳方式是什么,调用方不应该看到它的类型。

共有2个答案

佟嘉祯
2023-03-14

所以答案是否定的,因为它破坏了以前有效的代码。

魏松
2023-03-14

你使用临时的迭代,因此你的迭代器在矫揉造作后直接失效。

您可以使用以下选项:

auto&& view = d.test();
for (auto it = view.begin(), end = view.end(); it != end; ++it) {
    std::cout << *it << "\n";
}
 类似资料:
  • 问题内容: 我发现自己同意返回接口而不是具体的类。 原因很简单,我要松散耦合。 但是还会有其他影响或权衡吗? 问题答案: 对于List或ArrayList之类的类型,不应进行任何编译,并且应将List提升Code返回到接口。 如果这是通过诸如CopyOnWriteArrayList之类的并发包进行的,并且您使用的是addIfAbsent之类的方法(未在List接口中定义),您将发现自己受到限制。

  • 我发现自己同意返回一个接口,而不是一个具体的类。

  • 假设我有一个方法将只读视图返回到成员列表中: 进一步假设客户机所做的只是立即对列表进行一次迭代。也许是为了把玩家放进一个JList或者别的什么。客户端没有存储对列表的引用以供以后检查! 对于这种常见的场景,我是否应该返回一个流呢? 还是返回流在Java中不是惯用的?流被设计成总是在创建它们的同一个表达式中“终止”吗?

  • 问题内容: 假设我有一个将只读视图返回到成员列表的方法: 进一步假设所有客户要做的就是立即遍历列表一次。也许将播放器放入JList之类。客户端就不能存储到列表的引用以便稍后进行检查! 在这种常见情况下,我应该返回流吗? 还是在Java中返回流非惯用语?流是否设计为始终在创建它们的相同表达式内被“终止”? 问题答案: 答案是一如既往的“取决于”。这取决于返回的集合的大小。这取决于结果是否随时间变化,

  • 我有一个项目,其中我创建了一个BankAccount超级类和一个SavingsAccount子类。一切都很好,但我在返回我特别想要的字符串时遇到了麻烦。 示例:(裁剪) 驱动程序类将对BankAccount使用toString方法,并打印以下内容: (这对于这个超类来说是完美的) 但是,下面是SavingsAccount子类 调用SavingsAccount的toString方法时,它会打印: S

  • 我试图让2支球队互相比赛。当我说团队1.玩(团队2)时,我称之为;当 i 生成的数字小于 0.5 时,team2 应获胜,如果大于 0.5,则团队 1 应获胜。当团队 1 获胜时,它会正确显示为尼克斯,但当团队 2 获胜时,它会显示内存地址。我怎么能让它正确地说网是赢的,而不是team@78987neu73