:sad: Write a C++ template class Nvector that enables arrays with negative subscripts to be
defined. The class should be usable in the following code fragment:

Nvector<double> a; // instantiate double array class
a.resize(-10, 10); // allocate array from locations -10 to 10
for(int i=-10 ; i<=10 ; ++i)
a[i] = exp(-k*(T-t[i])); // fill array

<< moderator edit: added code tags: [code][/code] >>

The class should be written so that array set/access is optimally efficient. Show through the template specification that multidimensional arrays can also be defined.

Dani AI

Generated

The OP, , posted the assignment with no starter code; asked for progress and reminded about the homework policy. For an efficient container that accepts arbitrary integer indices the usual pattern is a single contiguous buffer plus an integer offset: translate external index -> internal index = i - low. This keeps operator[] O(1) and allows pointer/data() access for numeric kernels. Important design points: RAII for memory, well-defined copy/move semantics, optional bounds checking, and deciding whether resize preserves overlapping contents.

#include <memory>
#include <algorithm>
#include <cstddef>

template<typename T>
class Nvector {
    std::unique_ptr<T[]> data_;
    int low_ = 0, high_ = -1;
public:
    Nvector() = default;
    Nvector(int low, int high) { resize(low, high); }

    void resize(int low, int high) {
        if (high < low) { data_.reset(); low_ = 0; high_ = -1; return; }
        std::size_t n = static_cast<std::size_t>(high - low + 1);
        std::unique_ptr<T[]> tmp(new T[n]);
        if (data_) {
            int old_low = low_, old_high = high_;
            int lo = std::max(low, old_low), hi = std::min(high, old_high);
            for (int i = lo; i <= hi; ++i) tmp[i - low] = data_[i - old_low];
        }
        data_.swap(tmp); low_ = low; high_ = high;
    }

    T& operator[](int i) noexcept { return data_[i - low_]; }
    const T& operator[](int i) const noexcept { return data_[i - low_]; }

    std::size_t size() const { return (high_ >= low_) ? static_cast<std::size_t>(high_ - low_ + 1) : 0; }

    // deep copy semantics
    Nvector(const Nvector& o) { if (o.size()) { std::size_t n = o.size(); data_.reset(new T[n]); std::copy(o.data_.get(), o.data_.get()+n, data_.get()); low_ = o.low_; high_ = o.high_; } }
    Nvector& operator=(const Nvector& o) { if (this != &o) { Nvector tmp(o); swap(tmp); } return *this; }

    Nvector(Nvector&&) = default;
    Nvector& operator=(Nvector&&) = default;

    void swap(Nvector& o) noexcept { std::swap(data_, o.data_); std::swap(low_, o.low_); std::swap(high_, o.high_); }
};

Notes and pitfalls: operator[] above is unchecked for speed — add an at(int) that throws std::out_of_range if safety is required. Frequent small resizes are expensive; prefer a single allocation when ranges are known. For automatic capacity management and reserve semantics, using std::vector<T> internally is an easy alternative (std::vector). RAII with std::unique_ptr and move semantics is described at std::unique_ptr.

Multidimensional arrays can be expressed two ways: nested Nvector<Nvector<T>> for ragged rows, or a flattened single-allocation matrix (stride arithmetic) for best cache locality. The code above shows the offset idea; a contiguous 2D wrapper simply computes index = (r - rlow)*ncols + (c - clow) into a single Nvector<T>.

Recommended Answers

All 5 Replies

Okay, what do you have so far?

This is the question!

The only way to learn and master c++ is if you practice and get corrected....

With all the pace of continental drift, your reply to "urgent" took all of 2 YEARS.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.