自然地禁止C ++中的包装类

时间:2014-08-03 16:47:40

标签: c++ c++11

因此,我发现使用集合的算法更自然,而不是使用迭代器对。所以,我写了一些像

这样的函数
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类,除非我愿意,否则我会这样做找到更好的方法。但是我想以更一般的方式禁止它,所以类似的实现也将无法编译。

有什么想法吗?

2 个答案:

答案 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伪概念可能比特征类更好,或者可能对增强它有用。

相关问题