确定范围内的元素放置在连续内存中

Determine that elements in range placed in contiguous memory

假设我编写了处理一系列元素的模板函数。

template <typename Iter>
void func(Iter first, Iter last);

在这个函数中,我想调用一些低级的 c 函数,它希望获得连续的缓冲区及其大小。执行此操作的通用方法是将我的范围复制到连续容器,然后调用 c 函数。

template <typename Iter>
void func(Iter first, Iter last)
{
    typedef typename iterator_traits<Iter>::value_type value_type;
    vector<value_type> buf(first, last);
    c_func((void*) buf.data(), buf.size() * sizeof(value_type));
}

但是如果迭代器已经指向一些连续的内存space将执行额外的复制。

所以问题是,有没有一种方法可以确定迭代器是否指向连续内存 space,如果是,我该如何针对这种情况专门化我的函数。

目前没有直接的方法来确定迭代器是否用于连续内存。有一个添加迭代器改进的建议(参见 n3884)但是没有类似的东西和检测为不同迭代器添加的 属性 的方法你将很难确定这个特征.

需要实现者支持的关键问题是未指定迭代器类型的名称。因此,您无法创建适用于所有已知连续迭代器类型的特征。由于 std::vector<T>std::array<T> 的迭代器类型可以相同并且 T* 我认为您甚至无法创建可移植的专业化。

但是,您可以做的是在特征中测试迭代器类型是否与其值类型匹配的已知迭代器类型之一。例如:

template <typename T, typename It>
struct test_iterator
    : std::integral_constant<bool,
        std::is_same<T*, It>::value
        || std::is_same<typename std::vector<T>::iterator, It>::value
        || std::is_same<std::string::iterator, It>::value
        || std::is_same<std::wstring::iterator, It>::value
        > {
};
template <typename It>
struct is_contiguous
    : std::integral_constant<bool,
           test_iterator<typename std::iterator_traits<It>::value_type,
                         It>::value> {
};

[我没有尝试编译代码,也就是说,它可能到处都是小错别字;不过,一般方法应该有效]

要添加,例如,std::array<T, N>,您需要一些方法以静态方式计算维度。我想,那是行不通的。可能还需要测试各种 const_iterators.