Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Can I have a compile time bound check for std::array in the index is known to the compiler and normal behaviour otherwise?

As a simple example consider the following class:

template <int N>
class A {
private:
  std::array<double, N> m_vs = {};
public:
  int size() {return N;}
  void set_value(double d, int n=0) {m_vs[n] = d;}
  double get_value(int n=0) {return m_vs[n];}
}

Let’s say that we have a = A<10>().

I would like the compiler to throw an error if I type a.set_value(1, 20) since it is known that this will be out of bounds, but not throw any error if I write a.set_value(1, i) since i could be valid.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Is it possible to get such behaviour?

>Solution :

You won’t get a compile time check for your runtime value. You can get

  • Compiletime checks for your constexpr values
  • Runtime checks for runtime values

Example:

template <std::size_t N>
class A {
private:
    std::array<double, N> m_vs = {};

public:
    constexpr std::size_t size() const { return N; }

    // use these with runtime `n`s:
    double get_value(std::size_t n) {
        if (n >= N) throw std::out_of_range("get_value: n >= N");
        return m_vs[n];
    }

    void set_value(double d, std::size_t n) {
        if (n >= N) throw std::out_of_range("set_value: n >= N");
        m_vs[n] = d;
    }

    // use these with `n`s known at compile time:
    template <std::size_t n = 0>
    double get_value() {
        static_assert(n < N, "n < N failed");
        return m_vs[n];
    }

    template <std::size_t n = 0>
    void set_value(double d) {
        static_assert(n < N, "n < N failed");
        m_vs[n] = d;
    }
};

Usage:

int main() {
    A<10> a;

    a.set_value(3.141);      // n == 0, all's well (if N > 0, else compile time error)
    a.set_value<10>(3.141);  // compile time time error, 10 is out-of-bounds
    a.set_value(3.141, 10);  // runtime access out-of-bounds, throws exception
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading