如果我正在编写一个库,并且我有一个需要返回一系列值的函数,我可以这样做:
std::vector<int> get_sequence();
但是,这需要库用户使用std :: vector <>容器,而不是允许它们使用他们想要使用的任何容器。此外,它还可以添加返回数组的额外副本(取决于编译器是否可以优化),这可能会对性能产生负面影响。
理论上,您可以通过创建一个带有开始和结束的模板化函数来启用任意容器(并避免不必要的额外复制):
template<class T_iter> void get_sequence(T_iter begin, T_iter end);
然后,该函数将序列值存储在迭代器给定的范围内。但问题在于它需要您知道序列的大小,以便在序列之间存储足够的元素begin
并end
存储所有值。
我想过一个界面如:
template<T_insertIter> get_sequence(T_insertIter inserter);
这要求T_insertIter是一个插入迭代器(例如用它创建std::back_inserter(my_vector)
),但这似乎太容易被滥用,因为编译器很乐意接受非插入迭代器,但在运行时会表现不正确。
那么有一个最佳实践来设计返回任意长度序列的通用接口吗?
发布于 2018-12-11 10:02:49
我的想法:
void get_sequence(std::vector<int> & p_aInt);
这将通过复制问题消除潜在的回报。现在,如果你真的想避免强加一个容器,你可以尝试以下方法:
template <typename T>
void get_sequence(T & p_aInt)
{
p_aInt.push_back(25) ; // Or whatever you need to add
}
这将仅编译vector,lists和deque(以及类似的容器)。如果你想要一大堆可能的容器,代码将是:
template <typename T>
void get_sequence(T & p_aInt)
{
p_aInt.insert(p_aInt.end(), 25) ; // Or whatever you need to add
}
但正如其他帖子所说,您应该接受将您的界面限制为仅限一种容器。
发布于 2018-12-11 10:50:33
如果您已经为序列管理了内存,则可以返回一对迭代器,供调用者在for循环或算法调用中使用。
如果返回的序列需要管理自己的内存,那么事情会更复杂。您可以使用@ paercebal的解决方案,或者您可以实现自己的迭代器,将shared_ptr保存到它们迭代的序列中。
https://stackoverflow.com/questions/-100000935
复制相似问题