Russian Qt Forum

Программирование => С/C++ => Тема начата: Igors от Декабрь 20, 2017, 11:44



Название: Инициализация массивов в template
Отправлено: Igors от Декабрь 20, 2017, 11:44
Добрый день

Для примера есть простой статычный темплейт массив
Код
C++ (Qt)
template <class T>
struct TArray<T, size_t num> {
 TArray( void )
 {
   ???
 }
 
 T & operator[] ( size_t index );
 
private:
 T mData[num];
}
Теперь если T будет классом с конструктором - он, как положено, вызовется для каждого эл-та массива. Но если T простой POD тип (напр int или double) - эл-ты останутся "с мусором". Конечно можно прописать их в конструкторе TArray, но тогда получим избыточность в первом случае.

Не скажу что это "великая проблема" :), но все-таки интересно как сделать аккуратно.

Спасибо




Название: Re: Инициализация массивов в template
Отправлено: ksk- от Декабрь 20, 2017, 12:47
Можно применить std::is_pod


Название: Re: Инициализация массивов в template
Отправлено: ksk- от Декабрь 20, 2017, 12:50
А если есть 17-е плюсы, то вообще красиво получится. ))


Название: Re: Инициализация массивов в template
Отправлено: ViTech от Декабрь 20, 2017, 17:34
Код
C++ (Qt)
#include <iostream>
using namespace std;
 
template <class T, size_t num>
struct TArray
{
   T& operator[](size_t index) { return mData[index]; }
 
private:
   T mData[num];
};
 
int main()
{
   TArray<int, 5> a;
   cout << "Uninitialized: " << a[0] << endl;
 
   TArray<int, 5> b{};
   cout << "Initialized  : " << b[0] << endl;
 
   return 0;
}
можно mData инициализировать:
Код
C++ (Qt)
private:
   T mData[num]{};

Но лучше использовать std::array(даже вместо mData[num]), или наследоваться от него.


Название: Re: Инициализация массивов в template
Отправлено: Alex Custov от Декабрь 20, 2017, 19:02
mData поменять на указатель или std::trat-ta-ta-ptr, тогда можно сделать

Код
C++ (Qt)
mData = new T[num]();
 


Название: Re: Инициализация массивов в template
Отправлено: ksk- от Декабрь 20, 2017, 20:13
Примерно так может выглядеть конструктор (С++17):
Код
C++ (Qt)
TArray()
{
   if constexpr(std::is_pod_v<T>) {
       std::fill_n(std::begin(mData), num, T());
   }
}
 


Название: Re: Инициализация массивов в template
Отправлено: Igors от Декабрь 21, 2017, 15:43
Код
C++ (Qt)
   TArray<int, 5> a;
...
   TArray<int, 5> b{};
}
Ну так отличные шансы ошибиться :), тогда уж лучше потратиться на инициализацию. И эти скобочки С++ 11 ? (MSVC 2012 не кушает)


Название: Re: Инициализация массивов в template
Отправлено: ViTech от Декабрь 21, 2017, 16:04
Ну так отличные шансы ошибиться :), тогда уж лучше потратиться на инициализацию.

Это уже от поставленных задач зависит. Может нужна суперскорость и некогда на пустую инициализацию время тратить :). Для тех кто знает что они делают.

И эти скобочки С++ 11 ? (MSVC 2012 не кушает)

Да, скобочки - это инициализация из braced-init-list (http://en.cppreference.com/w/cpp/language/list_initialization) в С++11.


Название: Re: Инициализация массивов в template
Отправлено: _Bers от Декабрь 24, 2017, 21:31
 TArray( void )
  {
    ???
  }

Код:
template <class T, size_t N>
struct array
{
    T mData[N] = {};
};