벡터의 대안
우리 모두가 알고 있듯이 vector<bool>
완전히 깨져서 C 배열로 취급 될 수 없습니다. 이 기능을 얻는 가장 좋은 방법은 무엇입니까? 지금까지 내가 생각한 아이디어는 다음과 같습니다.
vector<char>
대신 사용 하거나- 래퍼 클래스를 사용하고
vector<bool_wrapper>
이 문제를 어떻게 처리합니까? c_array()
기능이 필요합니다 .
부수적 인 질문으로, c_array()
방법이 필요하지 않은 경우 임의 액세스가 필요한 경우이 문제에 접근하는 가장 좋은 방법은 무엇입니까? 데크 나 다른 것을 사용해야합니까?
편집하다:
- 동적 크기 조정이 필요합니다.
- 모르는 분들을 위해
vector<bool>
각각bool
1 비트를 취 하도록 특화되어 있습니다. 따라서 C 스타일 배열로 변환 할 수 없습니다. - 나는 "래퍼"가 약간 잘못된 이름이라고 생각한다. 나는 다음과 같이 생각하고 있었다.
물론 my_bool
정렬 문제로 인해를 읽어야 합니다.
struct my_bool
{
bool the_bool;
};
vector<my_bool> haha_i_tricked_you;
std::deque
어레이가 필요하지 않은 경우 사용하십시오 .
그렇지 않으면 Boost Container에 있는 것과 같이 vector
전문화되지 않은 대안 을 사용하십시오 .bool
흥미로운 문제입니다.
전문화되지 않았다면 std :: vector 였을 필요가 있다면 아마도 그와 같은 것이 귀하의 경우에 잘 작동 할 것입니다.
#include <vector>
#include <iostream>
#include <algorithm>
class Bool
{
public:
Bool(): m_value(){}
Bool( bool value ) : m_value(value){}
operator bool() const { return m_value;}
// the following operators are to allow bool* b = &v[0]; (v is a vector here).
bool* operator& () { return &m_value; }
const bool * const operator& () const { return &m_value; }
private:
bool m_value;
};
int main()
{
std::vector<Bool> working_solution(10, false);
working_solution[5] = true;
working_solution[7] = true;
for( int i = 0; i < working_solution.size(); ++i )
{
std::cout<< "Id " << i << " = " << working_solution[i] << "(" <<(working_solution[i] ? "true" : "false") << ")" <<std::endl; // i used ? : to be sure the boolean evaluation is correct
}
std::sort( working_solution.begin(), working_solution.end());
std::cout<< "--- SORTED! ---" << std::endl;
for( int i = 0; i < working_solution.size(); ++i )
{
bool* b = &working_solution[i]; // this works!
std::cout<< "Id " << i << " = " << working_solution[i] << "(" << (working_solution[i] ? "true" : "false") << ")" <<std::endl; // i used ? : to be sure the boolean evaluation is correct
}
std::cin.get();
return 0;
}
나는 VC9로 이것을 시도했고 잘 작동하는 것 같습니다. Bool 클래스의 아이디어는 동일한 동작과 크기 (동일한 유형은 아님)를 제공하여 bool 유형을 시뮬레이션하는 것입니다. 거의 모든 작업은 여기에서 bool 연산자와 기본 복사 생성자에 의해 수행됩니다. 알고리즘을 사용할 때 가정 한대로 반응하도록 정렬을 추가했습니다.
Not sure it would suit all cases. If it's right for your needs, it would be less work than rewriting a vector-like class...
Depends on your needs. I would go for either std::vector<unsigned char>
. Writting a wrapper can be fine if you only use a subset of the functionality, else it will become a nightmare.
How do you guys handle this problem? I need the c_array() functionality.
boost::container::vector<bool>
:
vector<bool> specialization has been quite problematic, and there have been several unsuccessful tries to deprecate or remove it from the standard.
Boost.Container
does not implement it as there is a superior Boost.DynamicBitset solution....
So boost::container::vector::iterator returns real bool references and works as a fully compliant container. If you need a memory optimized version of boost::container::vector<bool> functionalities, please use Boost.DynamicBitset.
Consider using a vector< int >. Once you get past compilation and type checking, bool and int are both just machine words (edit: apparently this is not always true; but will be true on many PC architectures). In those cases where you want to convert without a warning, use "bool foo = !!bar", which converts zero to false and non-zero to true.
A vector< char > or similar will use less space, though it also has the potential to take a (very small) speed hit in some circumstances, because characters are less than the machine word size. This is, I believe, the main reason that bools are implemented using ints instead of chars.
If you really want clean semantics, I also like the suggestion of making your own boolean class -- looks like a bool, acts like a bool, but fools the template specialization.
Also, welcome to the club of people who want the vector< bool > specialization dropped from the C++ standard (with bit_vector to replace it). It's where all the cool kids hang out :).
Simplest answer is use vector<struct sb>
where sb
is struct {boolean b};
. Then you can say push_back({true})
. It seems good.
This problem was already discussed on comp.lang.c++.moderated. Proposed solutions:
- your own allocator (based on
std::allocator
) and own vector specialization; - use
std::deque
(as early was recommended in one of books S. Mayers) - but this not for your requirements; - make POD
bool
wrapper; - use something (
char
/int
/etc) with same size asbool
insteadbool
;
Also early I saw proposal for standard committee - introduce macro (something like STD_VECTOR_BOOL_SPECIAL
) to disallow this specialization - but AFAIK this proposal was not implemented in stl implementations and wasn't approved.
It seems that your problem has no ways to do this nicely... Maybe in C++0x.
My preferred workaround is a vector
of a scoped enum that has an underlying type of bool
. This gets pretty close to the vector<bool>
we would have had if the committee hadn't specialised it.
enum class switch_status : bool { ON, OFF };
static_assert( sizeof( switch_status ) == 1 );
::std::vector<switch_status> switches( 20, switch_status::ON );
static_assert( ::std::is_same_v< decltype( switches.front() ), switch_status &> );
static_assert( ::std::is_same_v< decltype( switches.back() ), switch_status &> );
static_assert( ::std::is_same_v< decltype( switches[ 0 ] ), switch_status &> );
You will have your own opinions about the wisdom of embracing casts to/from bool
:
enum class switch_status : bool { OFF = false, ON = true };
static_assert( static_cast< bool >( switch_status::ON ) == true );
static_assert( static_cast< bool >( switch_status::OFF ) == false );
static_assert( static_cast< switch_status >( true ) == switch_status::ON );
static_assert( static_cast< switch_status >( false ) == switch_status::OFF );
참고URL : https://stackoverflow.com/questions/670308/alternative-to-vectorbool
'IT story' 카테고리의 다른 글
Android Room에서 엔티티의 특정 필드 업데이트 (0) | 2020.09.14 |
---|---|
Haskell의 예외는 어떻게 작동합니까? (0) | 2020.09.14 |
git-flow를 따라 이전 릴리스의 핫픽스를 어떻게 처리해야합니까? (0) | 2020.09.14 |
래퍼 클래스 및 기본 유형을 사용하는 경우 (0) | 2020.09.14 |
GitHub 코드 검색에서 문자를 어떻게 이스케이프합니까? (0) | 2020.09.14 |