Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 子数组模板_C++_Templates - Fatal编程技术网

C++ 子数组模板

C++ 子数组模板,c++,templates,C++,Templates,让我解释一下我在用代码寻找什么。让我们假设我们有一个包装数组的模板: template <typename T, std::size_t SIZE> struct wrap { using value_type = T; using wrap_type = wrap; static constexpr auto size = SIZE; T data[size]{}; }; 我不希望wrap::sub返回的??对象有两个指针,但有一个静态数组,因此

让我解释一下我在用代码寻找什么。让我们假设我们有一个包装数组的模板:

template <typename T, std::size_t SIZE>
struct wrap
{
    using value_type = T;
    using wrap_type = wrap;

    static constexpr auto size = SIZE;
    T data[size]{};
};
我不希望
wrap::sub
返回的
??
对象有两个指针,但有一个静态数组,因此我的方法是:

template <typename T, std::size_t SIZE>
struct wrap
{
    using value_type = T;
    using wrap_type = wrap;

    static constexpr auto size = SIZE;
    T data[size]{};

    template <std::size_t START, std::size_t COUNT>
    struct sub_array
    {
        using value_type = wrap_type::value_type *;

        static constexpr auto start = START;
        static constexpr auto count = COUNT;

        value_type data[count]{};
    };

    template <std::size_t START, std::size_t COUNT>
    sub_array<START, COUNT> sub() { ... }
};
我已经对其进行了测试,如下所示:

wrap<int, 9> w{1, 2, 3, 4, 5, 6, 7, 8, 9};

// x is the view [3, 4]
auto x = w.sub<2, 2>();

std::cout << *x.data[0] << '\n'; // shows 3

如何实现上述效果?

这解决了上述问题:

template<class=void, std::size_t...Is>
auto indexer( std::index_sequence<Is...> ) {
  return [](auto&& f){
    return decltype(f)(f)( std::integral_constant<std::size_t, Is>{}... );
  };
}
template<std::size_t N>
auto indexer() {
  return indexer( std::make_index_sequence<N>{} );
}
array\u视图
是讨论数组切片的一种简洁方式

如果你想迈步,你必须多做一些工作

我很确定使用
std::integer\u序列的方法应该是可行的

这是:

template <typename T, std::size_t SIZE>
struct wrap
{
    using value_type = T;
    using wrap_type = wrap;

    static constexpr auto size = SIZE;
    T data[size]{};

    template <std::size_t START, std::size_t COUNT>
    struct sub_array
    {
        using value_type = wrap_type::value_type *;

        static constexpr auto start = START;
        static constexpr auto count = COUNT;

        value_type data[count]{};
    };

    template <std::size_t START, std::size_t COUNT>
    constexpr sub_array<START, COUNT> sub() {
        static_assert(START + COUNT <= SIZE, "sub_array is out of range");
        // The argument makes an instance of integer sequence from 0 to COUNT-1
        return sub_impl<START, COUNT>(std::make_index_sequence<COUNT>{});
    }

private:

    template <std::size_t START, std::size_t COUNT, std::size_t ... Is>
    constexpr sub_array<START, COUNT> sub_impl(std::index_sequence<Is...>) {
        // Arithmetic in argument list expansion is pretty valid.
        return {&data[Is+START]...};
    }
};
模板
结构包裹
{
使用值_type=T;
使用wrap_type=wrap;
静态constexpr自动大小=大小;
T数据[大小]{};
模板
结构子数组
{
使用值类型=换行类型::值类型*;
静态constexpr自动启动=启动;
静态constexpr自动计数=计数;
值\类型数据[计数]{};
};
模板
constexpr sub_数组sub(){

static_assert(START+COUNT)作为实际数组的子数组不是
string_view
中的视图。它是数组某些部分的副本。这些是不同的概念。请澄清您希望从
sub()的返回值中得到什么确切属性
。属性是:使对象能够操作
wrap
对象中包含的数组的子部分。我将去掉
字符串视图
引用。您的设计将返回数组子部分的副本。对该子部分的更改不会反映在原始数组中,因为您创建了副本。Yo你在
return{data[START+Is]…}中有一个小错误;
在我的方法中,我不是复制原始数组的一个片段,而是创建一个指向原始数组值的指针数组(
{&data[START+Is]…}
)所以最后我将能够通过指针修改原始数组。@PaperBirdMaster等等,哦,那太糟糕了。存储一堆不同于
sizeof(T)的指针
是一种反模式;存储开始/结束指针将更简单、更高效,并且存储更少的无意义状态。嗯……我不知道你提到的那件事。我认为
子数组中的每个地址都应该是有效的。为了启发我,你有关于这个主题的链接吗?@PaperBirdMaster
>上面的array\u view
类型描述了我的意思。没有包含N个条目的数组,只有两个不同N的指针。
return { &data[START + 0], &data[START + 1], ... &data[START + n] };
template<class=void, std::size_t...Is>
auto indexer( std::index_sequence<Is...> ) {
  return [](auto&& f){
    return decltype(f)(f)( std::integral_constant<std::size_t, Is>{}... );
  };
}
template<std::size_t N>
auto indexer() {
  return indexer( std::make_index_sequence<N>{} );
}
template <std::size_t START, std::size_t SIZE>
sub_array<START, SIZE> sub() const {
  auto index = indexer<SIZE>();
  return index(
    [&](auto...Is)->sub_array<START, SIZE>
    {
      return {data[START+Is]...};
    }
  );
}
template<class T>
struct array_view {
  T* b = 0;
  T* e = 0;

  T* begin() const { return b; }
  T* end() const { return e; }

  T& operator[](std::size_t i)const { return begin()[i]; }

  bool empty() const { return begin()==end(); }
  std::size_t size() const { return end()-begin(); }

  array_view( T* s, T* f ):b(s), e(f) {}
  array_view( T* s, std::size_t l):array_view(s, s+l) {}

  array_view()=default;
  array_view(array_view const&)=default;
  array_view& operator=(array_view const&)=default;
};
template <typename T, std::size_t SIZE>
struct wrap
{
    using value_type = T;
    using wrap_type = wrap;

    static constexpr auto size = SIZE;
    T data[size]{};

    template <std::size_t START, std::size_t COUNT>
    struct sub_array
    {
        using value_type = wrap_type::value_type *;

        static constexpr auto start = START;
        static constexpr auto count = COUNT;

        value_type data[count]{};
    };

    template <std::size_t START, std::size_t COUNT>
    constexpr sub_array<START, COUNT> sub() {
        static_assert(START + COUNT <= SIZE, "sub_array is out of range");
        // The argument makes an instance of integer sequence from 0 to COUNT-1
        return sub_impl<START, COUNT>(std::make_index_sequence<COUNT>{});
    }

private:

    template <std::size_t START, std::size_t COUNT, std::size_t ... Is>
    constexpr sub_array<START, COUNT> sub_impl(std::index_sequence<Is...>) {
        // Arithmetic in argument list expansion is pretty valid.
        return {&data[Is+START]...};
    }
};
wrap<double, 10> ds{1,2,3,4,5,6,7,8,9,10};
auto s = ds.sub<2,3>();
std::cout << *s.data[0] << std::endl;