因此,我发现使用集合的算法更自然,而不是使用迭代器对。所以,我写了一些像
这样的函数template <typename R>
void sort(R& range) {
return std::sort(std::begin(range), std::end(range));
}
并且有可能处理部分集合,我已经编写了以下包装类,它只包含一对迭代器。
template <typename T>
class Range{
public:
Range(T begin, T end): begin_(begin), end_(end) {}
const T& begin() {
return begin_;
}
const T& end() {
return end_;
}
private:
T begin_, end_;
};
到那时一切都很好。现在我希望有一个函数可以复制/(尽可能移动)它的参数并返回新的集合。
我写了这样的话:
template <typename R>
R sorted(R range) {
sort(range);
return std::move(range);
}
这很好,除非我用我的包装器Range
类调用它内部集合已更改。我知道只有迭代器类型它通常不可能检索集合类型来创建新的集合,但我想至少不允许用这个Wrapper调用它。
我明白我可以使用static_assert
enable_if
来检查它是否属于特定Range
类,除非我愿意,否则我会这样做找到更好的方法。但是我想以更一般的方式禁止它,所以类似的实现也将无法编译。
有什么想法吗?
答案 0 :(得分:2)
您可以删除以下功能:
template <typename T>
void sorted(const Range<T>& range) = delete;
否则您可以禁止复制和移动对象,因此它只能与参考
一起使用template <typename T>
class Range{
public:
Range(const Range&) = delete;
Range(Range&&) = delete;
Range& operator =(const Range&) = delete;
Range& operator =(Range&&) = delete;
// previous code
};
答案 1 :(得分:2)
我会创建一个名为owning_container
的特征类。默认情况下,它会考虑作为范围的参数(您应该有一个特征类/概念constexpr - 如果begin(x)
在using std::begin;
的命名空间中返回迭代器,将其称为范围)并具有分配器(另一个特征)拥有(因为非拥有范围通常不需要分配器)以及C数组和std::arrays
拥有(通过专门化)。
这也允许我检测rvalue拥有容器并在某些上下文中移动它们的内容(将它们的迭代器更改为move
迭代器),而不对非拥有范围视图执行相同的操作。
如上所述,constexpr
伪概念可能比特征类更好,或者可能对增强它有用。