Я очень новичок в программировании на C++. Я хочу вставить элементы типа enum в vector<uint8_t>
? т.е. добавить все элементы std::vector <ValType> call
в std::vector<uint8_t> bravo
. Есть ли способ сделать это?
#include <stdio.h>
#include <vector>
#include <cstdint>
enum class ValType : uint8_t
{
Working = 1,
Failed = 0,
Freezed = 0
};
int main()
{
std::vector<uint8_t> bravo = {23, 23, 23, 22, 5};
std::vector<ValType> call;
bravo.insert(bravo.end(), call.begin(), call.end());
return 0;
}
Жить Здесь
При компиляции получаю ошибку:
In file included from c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\vector:66,
from custom.cpp:2:
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_uninitialized.h: In instantiation of '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<ValType*, std::vector<ValType> >; _ForwardIterator = unsigned char*]':
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_uninitialized.h:333:37: required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator<ValType*, std::vector<ValType> >; _ForwardIterator = unsigned char*; _Tp = unsigned char]'
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\vector.tcc:751:34: required from 'void std::vector<_Tp, _Alloc>::_M_range_insert(std::vector<_Tp, _Alloc>::iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = __gnu_cxx::__normal_iterator<ValType*, std::vector<ValType> >; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>; std::vector<_Tp, _Alloc>::iterator = std::vector<unsigned char>::iterator]'
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_vector.h:1665:19: required from 'void std::vector<_Tp, _Alloc>::_M_insert_dispatch(std::vector<_Tp, _Alloc>::iterator, _InputIterator, _InputIterator, std::__false_type) [with _InputIterator = __gnu_cxx::__normal_iterator<ValType*, std::vector<ValType> >; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>; std::vector<_Tp, _Alloc>::iterator = std::vector<unsigned char>::iterator]'
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_vector.h:1383:22: required from 'std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(std::vector<_Tp, _Alloc>::const_iterator, _InputIterator, _InputIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<ValType*, std::vector<ValType> >; <template-parameter-2-2> = void; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>; std::vector<_Tp, _Alloc>::iterator = std::vector<unsigned char>::iterator; std::vector<_Tp, _Alloc>::const_iterator = std::vector<unsigned char>::const_iterator]'
custom.cpp:18:17: required from here
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_uninitialized.h:138:72: error: static assertion failed: result type must be constructible from value type of input range
138 | static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
| ^~~~~
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_uninitialized.h:138:72: note: 'std::integral_constant<bool, false>::value' evaluates to false
In file included from c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\vector:60,
from custom.cpp:2:
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_algobase.h: In instantiation of 'static _OI std::__copy_move<false, false, std::random_access_iterator_tag>::__copy_m(_II, _II, _OI) [with _II = ValType*; _OI = unsigned char*]':
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_algobase.h:495:30: required from '_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = ValType*; _OI = unsigned char*]'
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_algobase.h:522:42: required from '_OI std::__copy_move_a1(_II, _II, _OI) [with bool _IsMove = false; _II = ValType*; _OI = unsigned char*]'
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_algobase.h:530:31: required from '_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = __gnu_cxx::__normal_iterator<ValType*, std::vector<ValType> >; _OI = __gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char> >]'
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_algobase.h:620:7: required from '_OI std::copy(_II, _II, _OI) [with _II = __gnu_cxx::__normal_iterator<ValType*, std::vector<ValType> >; _OI = __gnu_cxx::__normal_iterator<unsigned char*, std::vector<unsigned char> >]'
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\vector.tcc:744:16: required from 'void std::vector<_Tp, _Alloc>::_M_range_insert(std::vector<_Tp, _Alloc>::iterator, _ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = __gnu_cxx::__normal_iterator<ValType*, std::vector<ValType> >; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>; std::vector<_Tp, _Alloc>::iterator = std::vector<unsigned char>::iterator]'
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_vector.h:1665:19: required from 'void std::vector<_Tp, _Alloc>::_M_insert_dispatch(std::vector<_Tp, _Alloc>::iterator, _InputIterator, _InputIterator, std::__false_type) [with _InputIterator = __gnu_cxx::__normal_iterator<ValType*, std::vector<ValType> >; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>; std::vector<_Tp, _Alloc>::iterator = std::vector<unsigned char>::iterator]'
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_vector.h:1383:22: required from 'std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(std::vector<_Tp, _Alloc>::const_iterator, _InputIterator, _InputIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<ValType*, std::vector<ValType> >; <template-parameter-2-2> = void; _Tp = unsigned char; _Alloc = std::allocator<unsigned char>; std::vector<_Tp, _Alloc>::iterator = std::vector<unsigned char>::iterator; std::vector<_Tp, _Alloc>::const_iterator = std::vector<unsigned char>::const_iterator]'
custom.cpp:18:17: required from here
c:\program files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\include\c++\11.2.0\bits\stl_algobase.h:385:25: error: cannot convert 'ValType' to 'unsigned char' in assignment
385 | *__result = *__first;
| ~~~~~~~~~~^~~~~~~~~~
Может кто-нибудь показать мне правильный способ сделать это?
@Someprogrammerdude .. Извините, в онлайне было __uint8_t, а не uint8_t .. поэтому я поставил то же самое. вы можете предположить, что uint8_t
Включите <cstdint>
, который определяет стандартные целочисленные типы.
Отвечает ли это на ваш вопрос? Можно ли преобразовать класс перечисления в базовый тип?
Это объясняется, например. эта ссылка на перечисление области действия:
Нет неявных преобразований значений перечислителя с областью действия в целочисленные типы, хотя
static_cast
можно использовать для получения числового значения перечислителя.
[Emphasis mine]
Поэтому, хотя это может выглядеть как наследование при определении перечисления, это не так. Тип ValType
— это совершенно отдельный тип, который нельзя преобразовать в какой-либо другой простой целочисленный тип или из него, даже если он используется в качестве базового типа перечисления.
Это означает, что вы не можете просто скопировать вектор из ValType
элементов в вектор из uint8_t
элементов. Если вам нужно сделать такую копию, вы должны реализовать собственное преобразование (например, с помощью static_cast
), возможно, используя std::transform и итератор обратной вставки.
Спасибо .. If you need to do such a copy you must implement your own conversion (using e.g. static_cast), perhaps using std::transform and an back insert iterator.
не могли бы вы показать мне, как это сделать с моей проблемой?
Вы можете использовать std::transform
с собственной функцией преобразования.
std::vector<uint8_t> bravo = {23, 23, 23, 22, 5};
std::vector<ValType> call;
std::transform(bravo.cbegin(), bravo.cend(), std::back_inserter(call),
[](uint8_t a) { return static_cast<ValType>(a); });
Получение ошибки `ошибка: 'браво' не захвачено { return static_cast<ValType>(bravo[a]); });`
Код: #include <bits/stdc++.h> #include <stdio.h> #include <vector> enum class ValType: uint8_t {Работает = 1, Ошибка = 0, Заморожено = 0}; int main() { std::vector<uint8_t> bravo = {23, 23, 23, 22, 5}; вызов std::vector<ValType>; std::transform(bravo.cbegin(), bravo.cend(), std::back_inserter(call), [](uint8_t a) { return static_cast<ValType>(bravo[a]); }); вернуть 0; }
Загляните сюда onlinegdb.com/HRO8yJdIp .. Покажите, пожалуйста, как правильно?
@SenorMaldona обновил ответ. Теперь он должен скомпилироваться
@SenorMaldona onlinegdb.com/hWBePAJRy
Мурат Сагдикоглу.. Спасибо.. Но я думаю, ваш код делает противоположное тому, что я хочу. Я хочу добавить все элементы из вектора вызова в вектор браво... см. здесь onlinegdb.com/crYzDzbRm
Например, если std::vector<uint8_t> bravo = {23, 23, 23, 22, 5}
и std::vector<ValType> call = {7}
. затем добавьте элементы вызова в bravo. Следовательно, bravo становится {23, 23, 23, 22, 5 , 7}
Тогда вам следует поступить наоборот. Смотрите: onlinegdb.com/A17a5-Tuj
@SenorMaldona Кроме того, это причина, по которой он не скомпилировался в первый раз, когда вашей лямбде требуется доступ к переменным из-за пределов лямбда, переменная должна быть явно захвачена, только тогда у вас будет доступ к переменным за пределами области лямбда, обратитесь к этой ссылке для получения дополнительной информации, stackoverflow.com/questions/46809901/lambda-captures
@ ÖzgürMuratSağdıçoğlu, что, если мне нужно добавить только один элемент (не вектор)? Типа push_back(). т.е. std::vector<uint8_t> bravo .push_back(callelement)
callelement имеет тип ValType...
Если я вас правильно понял, если вы хотите сделать это для одного элемента, вы можете выполнить static_cast для аргумента push_back.
@Rajesh Как мне сделать это правильно, есть два способа 1) ValType Types = static_cast<ValType>(45); bravo.push_back(static_cast<std::underlying_type_t<ValType>>(Types));
2) bravo.push_back(static_cast<uint8_t>(Types));
Оба дают правильный результат. Подскажите, пожалуйста, какой из них лучше?
@SenorMaldona Я чувствую, что вам лучше выбрать вариант 2, так как он легко читается, менее многословен и четко передает намерение.
На несвязанный вопрос, почему вы используете нестандартный и непортативный
__uint8_t
вместо стандартногоuint8_t
?