2D counterpart of std::array in C++17












12












$begingroup$


I implemented a 2D counterpart of std::array named array2d in C++17. It is an aggregate like std::array, and provides similar interface. The goal is that if you know how to use std::array, then you will find yourself at home using array2d. Any comments are welcome :) For better viewing experience with highlighting, you can refer to this GitHub page.



#include <cstddef>
#include <array>
#include <iterator>

template <typename T, std::size_t N0, std::size_t N1>
struct array2d {
using row_t = std::array<T, N1>;
inline static constexpr std::array sizes{ N0, N1 };

static constexpr std::size_t size() noexcept { return N0 * N1; }
static constexpr bool empty() noexcept { return !size(); }

T& at(std::size_t i, std::size_t j) { return data_.at(i).at(j); }
const T& at(std::size_t i, std::size_t j) const { return data_.at(i).at(j); }

row_t& operator(std::size_t i) noexcept { return data_[i]; }
const row_t& operator(std::size_t i) const noexcept { return data_[i]; }

T& front() { return data_.front().front(); }
const T& front() const { return data_.front().front(); }

T& back() { return data_.back().back(); }
const T& back() const { return data_.back().back(); }

T* data() noexcept { return data_.data()->data(); }
const T* data() const noexcept { return data_.data()->data(); }

T* begin() noexcept { return data(); }
const T* begin() const noexcept { return data(); }

T* end() noexcept { return data() + size(); }
const T* end() const noexcept { return data() + size(); }

auto rbegin() noexcept { return std::make_reverse_iterator(end()); }
auto rbegin() const noexcept { return std::make_reverse_iterator(end()); }

auto rend() noexcept { return std::make_reverse_iterator(begin()); }
auto rend() const noexcept { return std::make_reverse_iterator(begin()); }

void fill(const T& v) {
for (auto& row : data_) {
row.fill(v);
}
}

friend void swap(array2d& a, array2d& b) { a.data_.swap(b.data_); }

std::array<row_t, N0> data_;
};









share|improve this question









$endgroup$

















    12












    $begingroup$


    I implemented a 2D counterpart of std::array named array2d in C++17. It is an aggregate like std::array, and provides similar interface. The goal is that if you know how to use std::array, then you will find yourself at home using array2d. Any comments are welcome :) For better viewing experience with highlighting, you can refer to this GitHub page.



    #include <cstddef>
    #include <array>
    #include <iterator>

    template <typename T, std::size_t N0, std::size_t N1>
    struct array2d {
    using row_t = std::array<T, N1>;
    inline static constexpr std::array sizes{ N0, N1 };

    static constexpr std::size_t size() noexcept { return N0 * N1; }
    static constexpr bool empty() noexcept { return !size(); }

    T& at(std::size_t i, std::size_t j) { return data_.at(i).at(j); }
    const T& at(std::size_t i, std::size_t j) const { return data_.at(i).at(j); }

    row_t& operator(std::size_t i) noexcept { return data_[i]; }
    const row_t& operator(std::size_t i) const noexcept { return data_[i]; }

    T& front() { return data_.front().front(); }
    const T& front() const { return data_.front().front(); }

    T& back() { return data_.back().back(); }
    const T& back() const { return data_.back().back(); }

    T* data() noexcept { return data_.data()->data(); }
    const T* data() const noexcept { return data_.data()->data(); }

    T* begin() noexcept { return data(); }
    const T* begin() const noexcept { return data(); }

    T* end() noexcept { return data() + size(); }
    const T* end() const noexcept { return data() + size(); }

    auto rbegin() noexcept { return std::make_reverse_iterator(end()); }
    auto rbegin() const noexcept { return std::make_reverse_iterator(end()); }

    auto rend() noexcept { return std::make_reverse_iterator(begin()); }
    auto rend() const noexcept { return std::make_reverse_iterator(begin()); }

    void fill(const T& v) {
    for (auto& row : data_) {
    row.fill(v);
    }
    }

    friend void swap(array2d& a, array2d& b) { a.data_.swap(b.data_); }

    std::array<row_t, N0> data_;
    };









    share|improve this question









    $endgroup$















      12












      12








      12





      $begingroup$


      I implemented a 2D counterpart of std::array named array2d in C++17. It is an aggregate like std::array, and provides similar interface. The goal is that if you know how to use std::array, then you will find yourself at home using array2d. Any comments are welcome :) For better viewing experience with highlighting, you can refer to this GitHub page.



      #include <cstddef>
      #include <array>
      #include <iterator>

      template <typename T, std::size_t N0, std::size_t N1>
      struct array2d {
      using row_t = std::array<T, N1>;
      inline static constexpr std::array sizes{ N0, N1 };

      static constexpr std::size_t size() noexcept { return N0 * N1; }
      static constexpr bool empty() noexcept { return !size(); }

      T& at(std::size_t i, std::size_t j) { return data_.at(i).at(j); }
      const T& at(std::size_t i, std::size_t j) const { return data_.at(i).at(j); }

      row_t& operator(std::size_t i) noexcept { return data_[i]; }
      const row_t& operator(std::size_t i) const noexcept { return data_[i]; }

      T& front() { return data_.front().front(); }
      const T& front() const { return data_.front().front(); }

      T& back() { return data_.back().back(); }
      const T& back() const { return data_.back().back(); }

      T* data() noexcept { return data_.data()->data(); }
      const T* data() const noexcept { return data_.data()->data(); }

      T* begin() noexcept { return data(); }
      const T* begin() const noexcept { return data(); }

      T* end() noexcept { return data() + size(); }
      const T* end() const noexcept { return data() + size(); }

      auto rbegin() noexcept { return std::make_reverse_iterator(end()); }
      auto rbegin() const noexcept { return std::make_reverse_iterator(end()); }

      auto rend() noexcept { return std::make_reverse_iterator(begin()); }
      auto rend() const noexcept { return std::make_reverse_iterator(begin()); }

      void fill(const T& v) {
      for (auto& row : data_) {
      row.fill(v);
      }
      }

      friend void swap(array2d& a, array2d& b) { a.data_.swap(b.data_); }

      std::array<row_t, N0> data_;
      };









      share|improve this question









      $endgroup$




      I implemented a 2D counterpart of std::array named array2d in C++17. It is an aggregate like std::array, and provides similar interface. The goal is that if you know how to use std::array, then you will find yourself at home using array2d. Any comments are welcome :) For better viewing experience with highlighting, you can refer to this GitHub page.



      #include <cstddef>
      #include <array>
      #include <iterator>

      template <typename T, std::size_t N0, std::size_t N1>
      struct array2d {
      using row_t = std::array<T, N1>;
      inline static constexpr std::array sizes{ N0, N1 };

      static constexpr std::size_t size() noexcept { return N0 * N1; }
      static constexpr bool empty() noexcept { return !size(); }

      T& at(std::size_t i, std::size_t j) { return data_.at(i).at(j); }
      const T& at(std::size_t i, std::size_t j) const { return data_.at(i).at(j); }

      row_t& operator(std::size_t i) noexcept { return data_[i]; }
      const row_t& operator(std::size_t i) const noexcept { return data_[i]; }

      T& front() { return data_.front().front(); }
      const T& front() const { return data_.front().front(); }

      T& back() { return data_.back().back(); }
      const T& back() const { return data_.back().back(); }

      T* data() noexcept { return data_.data()->data(); }
      const T* data() const noexcept { return data_.data()->data(); }

      T* begin() noexcept { return data(); }
      const T* begin() const noexcept { return data(); }

      T* end() noexcept { return data() + size(); }
      const T* end() const noexcept { return data() + size(); }

      auto rbegin() noexcept { return std::make_reverse_iterator(end()); }
      auto rbegin() const noexcept { return std::make_reverse_iterator(end()); }

      auto rend() noexcept { return std::make_reverse_iterator(begin()); }
      auto rend() const noexcept { return std::make_reverse_iterator(begin()); }

      void fill(const T& v) {
      for (auto& row : data_) {
      row.fill(v);
      }
      }

      friend void swap(array2d& a, array2d& b) { a.data_.swap(b.data_); }

      std::array<row_t, N0> data_;
      };






      c++ library template-meta-programming c++17






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 14 hours ago









      LingxiLingxi

      364113




      364113






















          1 Answer
          1






          active

          oldest

          votes


















          16












          $begingroup$

          Let me collect a couple of thoughts here.





          • Aggregate initialization currently works like this:



            array2d<int, 2, 2> a{{1, 2, 3, 4}};


            but wouldn't it be favorable to allow for



            array2d<int, 2, 2> a{{1, 2}, {3, 4}};


          • std::array::at performs bound checking and throws upon an out of bounds index. When your intention is to stick with the std::array interface, you should do the same.


          • If you want the container to be standard-compliant, there are some type aliases missing and maybe more. In particular, there are no cbegin(), cend(), crbegin(), crend() member functions. Is this intended?


          • You implicitly use row-major order. Are you sure everyone expects this? Users familiar with Eigen and their fixed size matrices might at least want to customize row-/column-major ordering, e.g. Eigen::Matrix<int, 2, 2, Eigen::ColMajor> m;



          • A range based for loop will considerably differ from a manual loop over rows and columns. Example:



            // Loop over elements, transposed access. Requires nested loop.
            for (std::size_t i = 0; i < 2; ++i)
            for (std::size_t j = 0; j < 2; ++j)
            std::cout << a[j][i] << "n";

            // Loop over elements, tranposed access impossible. Only one loop.
            for (const auto& i : d)
            std::cout << i << "n";


            This is slightly unintuitive. Shouldn't the range based for loop require a nested loop as well?



          • The static data member sizes is not used anywhere.



          Getting a two-dimensional array to work is not that much of an effort. Getting the semantics right is hard. Sticking to the std::array interface is a good goal when ease of use is intended for those familiar with the std::array template. But the additional dimension pulls in requirements that can't be tackled with the concepts of std::array. I would recommend having a look at established linear algebra libraries and their fixed size matrices. Also, the mdspan proposal for a multi-dimensional view on array types might be a good read.






          share|improve this answer










          New contributor




          lubgr is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.






          $endgroup$













          • $begingroup$
            Thanks for reviewing my code. 1) You can a{1, 2, 3, 4} and make a new line as you see fit. 2) array2d::at does bounds checking too, for array::at is called under the hood ^_^ 3) You are right they are missing. I think they are tedious and not very useful in practice. But again, the array2d is not very useful either XD 4) It is by design that the layout aligns with built-in two-dimensional array. 5) I intend the loop to be similar to what it does with array. User needs to use other interface if different traversal is desired. 6) sizes is part of the interface.
            $endgroup$
            – Lingxi
            9 hours ago










          • $begingroup$
            array2d is not meant to model matrix in linear algebra. Just like array and vector are not meant to model vector in linear algebra. By design, it's only meant to serve the role of a basic fixed-size 2D container. Hopefully more convenient to use than built-in 2D array and nested array.
            $endgroup$
            – Lingxi
            9 hours ago










          • $begingroup$
            You're right with the bounds checking of course :) Also, the point that array2d is not meant to be used as a linear algebra vocabulary type is obviously valid. I do see two issues with that, though: if you introduce array2d to a code base, developers might use it for linear algebra despite the fact that you didn't design it to fit these requirements. And, I personally use two-dimensional arrays for linear algebra and nothing else. If I need more that one dimension, I often find other data structures nearer to my intention.
            $endgroup$
            – lubgr
            9 hours ago











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215399%2f2d-counterpart-of-stdarray-in-c17%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          16












          $begingroup$

          Let me collect a couple of thoughts here.





          • Aggregate initialization currently works like this:



            array2d<int, 2, 2> a{{1, 2, 3, 4}};


            but wouldn't it be favorable to allow for



            array2d<int, 2, 2> a{{1, 2}, {3, 4}};


          • std::array::at performs bound checking and throws upon an out of bounds index. When your intention is to stick with the std::array interface, you should do the same.


          • If you want the container to be standard-compliant, there are some type aliases missing and maybe more. In particular, there are no cbegin(), cend(), crbegin(), crend() member functions. Is this intended?


          • You implicitly use row-major order. Are you sure everyone expects this? Users familiar with Eigen and their fixed size matrices might at least want to customize row-/column-major ordering, e.g. Eigen::Matrix<int, 2, 2, Eigen::ColMajor> m;



          • A range based for loop will considerably differ from a manual loop over rows and columns. Example:



            // Loop over elements, transposed access. Requires nested loop.
            for (std::size_t i = 0; i < 2; ++i)
            for (std::size_t j = 0; j < 2; ++j)
            std::cout << a[j][i] << "n";

            // Loop over elements, tranposed access impossible. Only one loop.
            for (const auto& i : d)
            std::cout << i << "n";


            This is slightly unintuitive. Shouldn't the range based for loop require a nested loop as well?



          • The static data member sizes is not used anywhere.



          Getting a two-dimensional array to work is not that much of an effort. Getting the semantics right is hard. Sticking to the std::array interface is a good goal when ease of use is intended for those familiar with the std::array template. But the additional dimension pulls in requirements that can't be tackled with the concepts of std::array. I would recommend having a look at established linear algebra libraries and their fixed size matrices. Also, the mdspan proposal for a multi-dimensional view on array types might be a good read.






          share|improve this answer










          New contributor




          lubgr is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.






          $endgroup$













          • $begingroup$
            Thanks for reviewing my code. 1) You can a{1, 2, 3, 4} and make a new line as you see fit. 2) array2d::at does bounds checking too, for array::at is called under the hood ^_^ 3) You are right they are missing. I think they are tedious and not very useful in practice. But again, the array2d is not very useful either XD 4) It is by design that the layout aligns with built-in two-dimensional array. 5) I intend the loop to be similar to what it does with array. User needs to use other interface if different traversal is desired. 6) sizes is part of the interface.
            $endgroup$
            – Lingxi
            9 hours ago










          • $begingroup$
            array2d is not meant to model matrix in linear algebra. Just like array and vector are not meant to model vector in linear algebra. By design, it's only meant to serve the role of a basic fixed-size 2D container. Hopefully more convenient to use than built-in 2D array and nested array.
            $endgroup$
            – Lingxi
            9 hours ago










          • $begingroup$
            You're right with the bounds checking of course :) Also, the point that array2d is not meant to be used as a linear algebra vocabulary type is obviously valid. I do see two issues with that, though: if you introduce array2d to a code base, developers might use it for linear algebra despite the fact that you didn't design it to fit these requirements. And, I personally use two-dimensional arrays for linear algebra and nothing else. If I need more that one dimension, I often find other data structures nearer to my intention.
            $endgroup$
            – lubgr
            9 hours ago
















          16












          $begingroup$

          Let me collect a couple of thoughts here.





          • Aggregate initialization currently works like this:



            array2d<int, 2, 2> a{{1, 2, 3, 4}};


            but wouldn't it be favorable to allow for



            array2d<int, 2, 2> a{{1, 2}, {3, 4}};


          • std::array::at performs bound checking and throws upon an out of bounds index. When your intention is to stick with the std::array interface, you should do the same.


          • If you want the container to be standard-compliant, there are some type aliases missing and maybe more. In particular, there are no cbegin(), cend(), crbegin(), crend() member functions. Is this intended?


          • You implicitly use row-major order. Are you sure everyone expects this? Users familiar with Eigen and their fixed size matrices might at least want to customize row-/column-major ordering, e.g. Eigen::Matrix<int, 2, 2, Eigen::ColMajor> m;



          • A range based for loop will considerably differ from a manual loop over rows and columns. Example:



            // Loop over elements, transposed access. Requires nested loop.
            for (std::size_t i = 0; i < 2; ++i)
            for (std::size_t j = 0; j < 2; ++j)
            std::cout << a[j][i] << "n";

            // Loop over elements, tranposed access impossible. Only one loop.
            for (const auto& i : d)
            std::cout << i << "n";


            This is slightly unintuitive. Shouldn't the range based for loop require a nested loop as well?



          • The static data member sizes is not used anywhere.



          Getting a two-dimensional array to work is not that much of an effort. Getting the semantics right is hard. Sticking to the std::array interface is a good goal when ease of use is intended for those familiar with the std::array template. But the additional dimension pulls in requirements that can't be tackled with the concepts of std::array. I would recommend having a look at established linear algebra libraries and their fixed size matrices. Also, the mdspan proposal for a multi-dimensional view on array types might be a good read.






          share|improve this answer










          New contributor




          lubgr is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.






          $endgroup$













          • $begingroup$
            Thanks for reviewing my code. 1) You can a{1, 2, 3, 4} and make a new line as you see fit. 2) array2d::at does bounds checking too, for array::at is called under the hood ^_^ 3) You are right they are missing. I think they are tedious and not very useful in practice. But again, the array2d is not very useful either XD 4) It is by design that the layout aligns with built-in two-dimensional array. 5) I intend the loop to be similar to what it does with array. User needs to use other interface if different traversal is desired. 6) sizes is part of the interface.
            $endgroup$
            – Lingxi
            9 hours ago










          • $begingroup$
            array2d is not meant to model matrix in linear algebra. Just like array and vector are not meant to model vector in linear algebra. By design, it's only meant to serve the role of a basic fixed-size 2D container. Hopefully more convenient to use than built-in 2D array and nested array.
            $endgroup$
            – Lingxi
            9 hours ago










          • $begingroup$
            You're right with the bounds checking of course :) Also, the point that array2d is not meant to be used as a linear algebra vocabulary type is obviously valid. I do see two issues with that, though: if you introduce array2d to a code base, developers might use it for linear algebra despite the fact that you didn't design it to fit these requirements. And, I personally use two-dimensional arrays for linear algebra and nothing else. If I need more that one dimension, I often find other data structures nearer to my intention.
            $endgroup$
            – lubgr
            9 hours ago














          16












          16








          16





          $begingroup$

          Let me collect a couple of thoughts here.





          • Aggregate initialization currently works like this:



            array2d<int, 2, 2> a{{1, 2, 3, 4}};


            but wouldn't it be favorable to allow for



            array2d<int, 2, 2> a{{1, 2}, {3, 4}};


          • std::array::at performs bound checking and throws upon an out of bounds index. When your intention is to stick with the std::array interface, you should do the same.


          • If you want the container to be standard-compliant, there are some type aliases missing and maybe more. In particular, there are no cbegin(), cend(), crbegin(), crend() member functions. Is this intended?


          • You implicitly use row-major order. Are you sure everyone expects this? Users familiar with Eigen and their fixed size matrices might at least want to customize row-/column-major ordering, e.g. Eigen::Matrix<int, 2, 2, Eigen::ColMajor> m;



          • A range based for loop will considerably differ from a manual loop over rows and columns. Example:



            // Loop over elements, transposed access. Requires nested loop.
            for (std::size_t i = 0; i < 2; ++i)
            for (std::size_t j = 0; j < 2; ++j)
            std::cout << a[j][i] << "n";

            // Loop over elements, tranposed access impossible. Only one loop.
            for (const auto& i : d)
            std::cout << i << "n";


            This is slightly unintuitive. Shouldn't the range based for loop require a nested loop as well?



          • The static data member sizes is not used anywhere.



          Getting a two-dimensional array to work is not that much of an effort. Getting the semantics right is hard. Sticking to the std::array interface is a good goal when ease of use is intended for those familiar with the std::array template. But the additional dimension pulls in requirements that can't be tackled with the concepts of std::array. I would recommend having a look at established linear algebra libraries and their fixed size matrices. Also, the mdspan proposal for a multi-dimensional view on array types might be a good read.






          share|improve this answer










          New contributor




          lubgr is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.






          $endgroup$



          Let me collect a couple of thoughts here.





          • Aggregate initialization currently works like this:



            array2d<int, 2, 2> a{{1, 2, 3, 4}};


            but wouldn't it be favorable to allow for



            array2d<int, 2, 2> a{{1, 2}, {3, 4}};


          • std::array::at performs bound checking and throws upon an out of bounds index. When your intention is to stick with the std::array interface, you should do the same.


          • If you want the container to be standard-compliant, there are some type aliases missing and maybe more. In particular, there are no cbegin(), cend(), crbegin(), crend() member functions. Is this intended?


          • You implicitly use row-major order. Are you sure everyone expects this? Users familiar with Eigen and their fixed size matrices might at least want to customize row-/column-major ordering, e.g. Eigen::Matrix<int, 2, 2, Eigen::ColMajor> m;



          • A range based for loop will considerably differ from a manual loop over rows and columns. Example:



            // Loop over elements, transposed access. Requires nested loop.
            for (std::size_t i = 0; i < 2; ++i)
            for (std::size_t j = 0; j < 2; ++j)
            std::cout << a[j][i] << "n";

            // Loop over elements, tranposed access impossible. Only one loop.
            for (const auto& i : d)
            std::cout << i << "n";


            This is slightly unintuitive. Shouldn't the range based for loop require a nested loop as well?



          • The static data member sizes is not used anywhere.



          Getting a two-dimensional array to work is not that much of an effort. Getting the semantics right is hard. Sticking to the std::array interface is a good goal when ease of use is intended for those familiar with the std::array template. But the additional dimension pulls in requirements that can't be tackled with the concepts of std::array. I would recommend having a look at established linear algebra libraries and their fixed size matrices. Also, the mdspan proposal for a multi-dimensional view on array types might be a good read.







          share|improve this answer










          New contributor




          lubgr is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          share|improve this answer



          share|improve this answer








          edited 11 hours ago





















          New contributor




          lubgr is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          answered 12 hours ago









          lubgrlubgr

          2615




          2615




          New contributor




          lubgr is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.





          New contributor





          lubgr is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.






          lubgr is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.












          • $begingroup$
            Thanks for reviewing my code. 1) You can a{1, 2, 3, 4} and make a new line as you see fit. 2) array2d::at does bounds checking too, for array::at is called under the hood ^_^ 3) You are right they are missing. I think they are tedious and not very useful in practice. But again, the array2d is not very useful either XD 4) It is by design that the layout aligns with built-in two-dimensional array. 5) I intend the loop to be similar to what it does with array. User needs to use other interface if different traversal is desired. 6) sizes is part of the interface.
            $endgroup$
            – Lingxi
            9 hours ago










          • $begingroup$
            array2d is not meant to model matrix in linear algebra. Just like array and vector are not meant to model vector in linear algebra. By design, it's only meant to serve the role of a basic fixed-size 2D container. Hopefully more convenient to use than built-in 2D array and nested array.
            $endgroup$
            – Lingxi
            9 hours ago










          • $begingroup$
            You're right with the bounds checking of course :) Also, the point that array2d is not meant to be used as a linear algebra vocabulary type is obviously valid. I do see two issues with that, though: if you introduce array2d to a code base, developers might use it for linear algebra despite the fact that you didn't design it to fit these requirements. And, I personally use two-dimensional arrays for linear algebra and nothing else. If I need more that one dimension, I often find other data structures nearer to my intention.
            $endgroup$
            – lubgr
            9 hours ago


















          • $begingroup$
            Thanks for reviewing my code. 1) You can a{1, 2, 3, 4} and make a new line as you see fit. 2) array2d::at does bounds checking too, for array::at is called under the hood ^_^ 3) You are right they are missing. I think they are tedious and not very useful in practice. But again, the array2d is not very useful either XD 4) It is by design that the layout aligns with built-in two-dimensional array. 5) I intend the loop to be similar to what it does with array. User needs to use other interface if different traversal is desired. 6) sizes is part of the interface.
            $endgroup$
            – Lingxi
            9 hours ago










          • $begingroup$
            array2d is not meant to model matrix in linear algebra. Just like array and vector are not meant to model vector in linear algebra. By design, it's only meant to serve the role of a basic fixed-size 2D container. Hopefully more convenient to use than built-in 2D array and nested array.
            $endgroup$
            – Lingxi
            9 hours ago










          • $begingroup$
            You're right with the bounds checking of course :) Also, the point that array2d is not meant to be used as a linear algebra vocabulary type is obviously valid. I do see two issues with that, though: if you introduce array2d to a code base, developers might use it for linear algebra despite the fact that you didn't design it to fit these requirements. And, I personally use two-dimensional arrays for linear algebra and nothing else. If I need more that one dimension, I often find other data structures nearer to my intention.
            $endgroup$
            – lubgr
            9 hours ago
















          $begingroup$
          Thanks for reviewing my code. 1) You can a{1, 2, 3, 4} and make a new line as you see fit. 2) array2d::at does bounds checking too, for array::at is called under the hood ^_^ 3) You are right they are missing. I think they are tedious and not very useful in practice. But again, the array2d is not very useful either XD 4) It is by design that the layout aligns with built-in two-dimensional array. 5) I intend the loop to be similar to what it does with array. User needs to use other interface if different traversal is desired. 6) sizes is part of the interface.
          $endgroup$
          – Lingxi
          9 hours ago




          $begingroup$
          Thanks for reviewing my code. 1) You can a{1, 2, 3, 4} and make a new line as you see fit. 2) array2d::at does bounds checking too, for array::at is called under the hood ^_^ 3) You are right they are missing. I think they are tedious and not very useful in practice. But again, the array2d is not very useful either XD 4) It is by design that the layout aligns with built-in two-dimensional array. 5) I intend the loop to be similar to what it does with array. User needs to use other interface if different traversal is desired. 6) sizes is part of the interface.
          $endgroup$
          – Lingxi
          9 hours ago












          $begingroup$
          array2d is not meant to model matrix in linear algebra. Just like array and vector are not meant to model vector in linear algebra. By design, it's only meant to serve the role of a basic fixed-size 2D container. Hopefully more convenient to use than built-in 2D array and nested array.
          $endgroup$
          – Lingxi
          9 hours ago




          $begingroup$
          array2d is not meant to model matrix in linear algebra. Just like array and vector are not meant to model vector in linear algebra. By design, it's only meant to serve the role of a basic fixed-size 2D container. Hopefully more convenient to use than built-in 2D array and nested array.
          $endgroup$
          – Lingxi
          9 hours ago












          $begingroup$
          You're right with the bounds checking of course :) Also, the point that array2d is not meant to be used as a linear algebra vocabulary type is obviously valid. I do see two issues with that, though: if you introduce array2d to a code base, developers might use it for linear algebra despite the fact that you didn't design it to fit these requirements. And, I personally use two-dimensional arrays for linear algebra and nothing else. If I need more that one dimension, I often find other data structures nearer to my intention.
          $endgroup$
          – lubgr
          9 hours ago




          $begingroup$
          You're right with the bounds checking of course :) Also, the point that array2d is not meant to be used as a linear algebra vocabulary type is obviously valid. I do see two issues with that, though: if you introduce array2d to a code base, developers might use it for linear algebra despite the fact that you didn't design it to fit these requirements. And, I personally use two-dimensional arrays for linear algebra and nothing else. If I need more that one dimension, I often find other data structures nearer to my intention.
          $endgroup$
          – lubgr
          9 hours ago


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215399%2f2d-counterpart-of-stdarray-in-c17%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Category:香港粉麵

          List *all* the tuples!

          Channel [V]