문제
크기가 다를 수있는 일부 구조물 포함이 비트 필드가 있습니다. 예시:
struct BitfieldSmallBase {
uint8_t a:2;
uint8_t b:3;
....
}
struct BitfieldLargeBase {
uint8_t a:4;
uint8_t b:5;
....
}
그리고 a 노동 조합 한 번에 모든 비트에 액세스하려면 :
template<typename T>
union Bitfield
{
T bits;
uint8_t all; // <------------- Here is the problem
bool operator & (Bitfield<T> x) const {
return !!(all & x.all);
}
Bitfield<T> operator + (Bitfield<T> x) const {
Bitfield<T> temp;
temp.all = all + x.all; //works, because I can assume no overflow will happen
return temp;
}
....
}
typedef Bitfield<BitfieldSmallBase> BitfieldSmall;
typedef Bitfield<BitfieldLargeBase> BitfieldLarge;
문제는 : 일부 비트 필드베이스 클래스의 경우 UINT8_T만으로는 충분하지 않습니다. BitfieldSmall은 UINT8_T에 적합하지만 BitfieldLarge는 그렇지 않습니다. 데이터는 가능한 한 단단히 포장되어야합니다 (나중에 SSE 지침에 의해 처리됩니다) 따라서 항상 UINT16_T를 사용하는 데 의문이 없습니다. "모든"필드를 적분 유형으로 선언하는 방법이 있습니까? 크기는 비트 필드와 동일합니까? 아니면 전체적으로 비트에 액세스하는 또 다른 방법?
물론 템플릿의 사용을 포기하고 모든 종류의 비트 필드를 명시 적으로 선언 할 수 있지만 코드 반복을 피하고 싶습니다 (운영자 UND 회원 기능 목록이 있습니다).
해결책
적분 유형 A 템플릿 매개 변수도 만들 수 있습니다.
template<typename T, typename U>
union Bitfield
{
T bits;
U all;
}
typedef Bitfield<BitfieldSmallBase, uint8_t> BitfieldSmall;
typedef Bitfield<BitfieldLargeBase, uint16_t> BitfieldLarge;
다른 팁
나는 당신이 사용하고있는 Vars의 비트 너비가 컴파일러가 당신을 위해 당신을 위해 당신의 마스킹을 수행하도록하는 편리한 방법이라는 어려운 방법을 배웠습니다. 할 수 없습니다 구조물에서 구성원의 순서와 패딩에 대해 가정합니다. 컴파일러 종속 및 컴파일러는 실제로 순서를 변경하고 프로젝트의 다른 코드에 따라 달라집니다.
바이트를 개별 필드로 취급하려면 실제로 어려운 방법으로해야합니다.
Template Metaprogramming을 사용하여 BitfieldsMallbase, BitfieldLargebase 등의 다른 유형으로 맵핑하는 템플릿 함수를 기본적으로 UINT8_T 및 BitfieldLargeBase의 경우 UINT16_T로 템플릿 전문화로 정의 할 수 있습니다.
union Bitfield
{
T bits;
typename F<T>::holder_type all;
};
고려하고 싶을 수도 있습니다 std :: 비트 셋 또는 부스트 :: dynamic_bitset 자신을 굴리는 대신. 어쨌든 피하십시오 std::vector<bool>
!
템플릿 매개 변수의 일부가 필요한 바이트 수를 만드십시오.
template <typename T, int S=1>
struct BitField
{
union
{
T bits;
unsigned char bytes[S];
};
};
typedef Bitfield<BitfieldSmallBase, 1> BitfieldSmall;
typedef Bitfield<BitfieldLargeBase, 2> BitfieldLarge;
이건 어때?
#include <limits.h>
template <class T>
union BitField
{
T bits;
unsigned all : sizeof(T) * CHAR_BIT;
};