Using static_assert() in a class template - C++ template

C++ examples for template:template class

Description

Using static_assert() in a class template

#include <iostream>
#include <iomanip>
#include <stdexcept>                        // For standard exception types
#include <string>                           // For to_string()
#include <type_traits>

class Pool
{
protected:
  double length {1.0};
  double width {1.0};
  double height {1.0};


public:
  Pool(double lv, double wv, double hv) : length {lv}, width {wv}, height {hv} {}
//  Pool() = default;

  double volume() const { return length*width*height; }
};


template <typename T>
class Array
{
  static_assert(std::is_default_constructible<T>::value, "A default constructor is required.");
private:
  T* elements;                              // Array of type T
  int size;                              // Number of array elements

public:
  explicit Array(int arraySize);         // Constructor
  Array(const Array& array);                // Copy Constructor
  ~Array();                                 // Destructor
  T& operator[](int index);              // Subscript operator
  const T& operator[](int index) const;  // Subscript operator-const arrays
  Array& operator=(const Array& rhs);       // Assignment operator
  int getSize() { return size; }         // Accessor for size
};

// Constructor
template <typename T>                       // This is a template with parameter T
inline Array<T>::Array(int arraySize) try : size {arraySize}, elements {new T[arraySize]}
{}
catch (std::bad_alloc& )
{
  std::cerr << "memory allocation failed for Array object creation.\n";
}

// Copy constructor
template <typename T>
inline Array<T>::Array(const Array& array) try : size {array.size}, elements {new T[array.size]}
{
  for (int i {}; i < size; ++i)
    elements[i] = array.elements[i];
}
catch (std::bad_alloc&)
{
  std::cerr << "memory allocation failed for Array object copy.\n";
}

// Destructor
template <typename T> inline Array<T>::~Array()
{
  delete[] elements;
}

// Subscript operator
template <typename T> inline T& Array<T>::operator[](int index)
{
  if (index >= size) throw std::out_of_range {"Index too large: " + std::to_string(index)};

  return elements[index];
}

// const subscript operator
template <typename T> inline const T& Array<T>::operator[](int index) const
{
  if (index >= size) throw std::out_of_range {"Index too large: " + std::to_string(index)};

  return elements[index];
}

// Assignment operator
template <typename T> inline Array<T>& Array<T>::operator=(const Array& rhs)
try
{
  if (&rhs != this)                         // If lhs != rhs...
  {                                         // ...do the assignment...
    if (elements)                           // If lhs array exists
      delete[] elements;                    // release the free store memory

    size = rhs.size;
    elements = new T[rhs.size];
    for (int i {}; i < size; ++i)
      elements[i] = rhs.elements[i];
  }
  return *this;                              // ... return lhs
}
catch (std::bad_alloc&)
{
  std::cerr << "memory allocation failed for Array assignment.\n";
}
int main()
{
  const int nValues {50};
  Array<double> values {nValues};                // Class constructor instance created
  try
  {
    for (int i {}; i < nValues; ++i)
      values[i] = i + 1;                         // Member function instance created

    std::cout << "Sums of pairs of elements:";
    int lines {};
    for (int i {nValues - 1} ; i >= 0 ; i--)
      std::cout << (lines++ % 5 == 0 ? "\n" : "")
      << std::setw(5) << values[i] + values[i - 1];
  }
  catch (const std::out_of_range& ex)
  {
    std::cerr << "\nout_of_range exception object caught! " << ex.what() << std::endl;
  }

  try
  {
    const int nPools {10};
    Array<Pool> pools {nPools};                   // Template instance created
    for (int i {} ; i <= nPools ; ++i)        // Member instance created in loop
      std::cout << "Pool volume is " << pools[i].volume() << std::endl;
  }
  catch (const std::out_of_range& ex)
  {
    std::cerr << "\nout_of_range exception object caught! " << ex.what() << std::endl;
  }
}

Related Tutorials