我有一节课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永远不会失败。基于循环的范围当然可以工作,但是这个循环是有效的,因此也必须按照预期工作。我已经预料到,来自同一容器的同一范围的所有跨度都是相等的,所以这些跨度的迭代器是可比的(当然容器没有修改)。当然,这不是这样有一个很好的理由。
所以我的问题是,将这样一个视图返回给数组类容器的元素的最佳方式是什么,调用方不应该看到它的类型。
所以答案是否定的,因为它破坏了以前有效的代码。
你使用临时的迭代器
,因此你的迭代器
在矫揉造作后直接失效。
您可以使用以下选项:
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