Явное преобразование неизвестных типов для размера вектора
У меня есть количество элементов type_1 n и размер каждого элемента type_2 size. Я хочу создать вектор размера n * size. Типы type_1 и type_2 неизвестные шаблонные. Надо ли делать какие-то явные преобразования типов/проверки или достаточно написать n * size?
Тип элемента вектора роли не играет, он фиксирован и не зависит от n и size.
Ответы (2 шт):
Это же вектор, он сам размер элемента посчитает и его сразу можно попросить выделить достаточно памяти.
template<typename T>
void foo(size_t size)
{
std::vector<T> v(size); // это будет вектор нужного типа и уже нужного размера
// можно пользоваться вектором v
}
int main()
{
foo<int>(100);//зададим тип и желаемый размер
}
upd
попытка угадать желание
#include <type_traits>
#include <cassert>
template<typename T, typename N>
void foo(N size)
{
// проверим, что тип беззнаковый
static_assert(std::is_unsigned<N>::value, "unsigned type only");
std::vector<T> v;
// проверим, что оно влезет
assert(v.max_size() > size);
// создадим вектор нужного размера
v.resize(size);
}
и теперь вот так
foo<int>(100u);
будет работать, а вот так
foo<int>(100);
уже нет.
Например, так:
#include <limits>
...
type_1 n = ...;
type_2 size = ...;
typedef std::vector<some_type>::size_type size_type;
if (std::numeric_limits<size_type>::max() / size >= n)
{
std::vector<some_type> vect(size_type(size) * n); //Помним, что здесь всё ещё может быть сгенерировано исключение
...
}
Условие std::numeric_limits<size_type>::max() / size >= n гарантирует, что результат произведения size_type(size) * n представим типом std::vector<some_type>::size_type точно, без всяких модулярных арифметик и неопределённых поведений. Следовательно, его можно спокойно передавать в методы вектора, не опасаясь усечения.
Тем не менее, это ещё не значит, что вектор заданного размера будет успешно сконструирован:
- Нельзя сконструировать вектор, количество элементов которого больше, чем значение, возвращаемое методом
max_size(), - При конструировании вектора размером меньше, чем
max_size(), всё ещё есть ненулевой шанс, что просто-напросто не хватит памяти.