How to reorganize functions that have the same lines with a difference of only one function call?

Consider the following code snippet

template <typename T>
void MyDynamicArray<T>::resize(size_t count)
{
    size_t prev_count = Count();
    if(count < prev_count)
    {
       DestroyMemory(prev_count, count);
    }
    else if(count > prev_count)
    {
      Reserve(count);

      for(size_t i=prev_count; i<count; i++)
      {
         // change in function call
         m_block.DefaultConstruct();
      }
    }
  }

And here is the overload for the same function

  template<typename T>
  void MyDynamicArray<T>::resize(const T &object, size_t count)
  {
     size_t prev_count = Count();
    if(count < prev_count)
    {
       DestroyMemory(prev_count, count);
    }
    else if(count > prev_count)
    {
      Reserve(count);

      for(size_t i=prev_count; i<count; i++)
      {
         // change in function call
         m_block.CopyConstruct(object);
      }
    }
  }

In one case, I think the resactoring resize function is intended to provide const T * pObject as the default argument. And check if provided, then call CopyConstruct.

Another way could be to provide one size dimension as a kind of shell that causes another size change.

What is the best approach?

+4
source share
2 answers

, m_block.Construct(), , :

struct default_construct_t { };

, :

template <typename T>
void MyDynamicArray<T>::resize(size_t count) {
    resize(count, default_construct_t());
}

template <typename T, typename Obj>
void MyDynamicArray<T>::resize(size_t count, Obj const& obj)
{
    size_t prev_count = Count();
    if(count < prev_count)
    {
       DestroyMemory(prev_count, count);
    }
    else if(count > prev_count)
    {
      Reserve(count);

      for(size_t i=prev_count; i<count; i++)
      {
         // change in function call
         m_block.Construct(obj);
      }
    }
  }

Construct(default_construct_t ) Construct(T const& ).

0

, " ", , . , , , :

template <typename T>
void MyDynamicArray<T>::resize(size_t count)
{
    resize_common(count, [] { m_block.DefaultConstruct(); });
}

template <typename T>
void MyDynamicArray<T>::resize(const T &object, size_t count)
{
    resize_common(count, [&] { m_block.CopyConstruct(object); });
}

template <typename T, typename lambda_t>
void MyDynamicArray<T>::resize_common(size_t count, lambda_t &&lambda)
{
    size_t prev_count = Count();
    if(count < prev_count)
    {
       DestroyMemory(prev_count, count);
    }
    else if(count > prev_count)
    {
      Reserve(count);

      for(size_t i=prev_count; i<count; i++)
      {
         lambda();
      }
    }
}

, , , , :

template <typename T>
void MyDynamicArray<T>::resize(size_t count)
{
    resize_common(count, null);
}

template <typename T>
void MyDynamicArray<T>::resize(const T &object, size_t count)
{
    resize_common(count, &object);
}

template <typename T>
void MyDynamicArray<T>::resize_common(size_t count, const T *object)
{
    size_t prev_count = Count();
    if(count < prev_count)
    {
       DestroyMemory(prev_count, count);
    }
    else if(count > prev_count)
    {
      Reserve(count);

      for(size_t i=prev_count; i<count; i++)
      {
         if (object)
              m_block.CopyConstruct(*object);
         else
              m_block.DefaultConstruct();
      }
    }
}

, . , " " , , , . ? ? ....

0

Source: https://habr.com/ru/post/1654302/


All Articles