2014-10-10 3 views
0

Я испытываю, по крайней мере, для меня странное поведение при применении оператора sizeof к специализации шаблона. Рассмотрим эти объявления:Шаблон специализации struct size

#pragma pack(push, 1) 

template <bool enable> 
struct RGB_data { 
    typedef unsigned char typeRGB; 
    typeRGB R; 
    typeRGB G; 
    typeRGB B; 
}; 
template <> struct RGB_data<false> {}; 

template <bool enable> 
struct XYZ_data { 
    typedef float type3D; 
    type3D X; 
    type3D Y; 
    type3D Z; 
}; 
template<> struct XYZ_data<false> {}; 

template <bool enable> 
struct Alpha_data { 
    typedef unsigned char typeAlpha; 
    typeAlpha A; 
}; 
template<> struct Alpha_data<false> {}; 

template <bool enable> 
struct Confidence_data { 
    typedef unsigned char typeConfidence; 
    typeConfidence C; 
}; 
template<> struct Confidence_data<false> {}; 


template < 
    bool enableXYZ, 
    bool enableRGB, 
    bool enableC, 
    bool enableA 
> 
struct Pixel : 
    public XYZ_data<enableXYZ>, 
    public RGB_data<enableRGB>, 
    public Alpha_data<enableA>, 
    public Confidence_data<enableC> 
{}; 

typedef Pixel<true,false,false,false> Pixel3D; 
typedef Pixel<true,false,true,false> Pixel3Dc; 

#pragma pack(pop) 

Однако размер Pixel3Dc структуры составляет 14 байт; размер Pixel3D также составляет 14 байтов. Размеры используемых типов данных 1 и 4 для unsigned char и float, соответственно.

Где дополнительные байты и как я могу получить размер структуры, соответствующий размеру содержащихся данных?

Окружающая среда - VS 9.0, Windows7 x64, Скомпилировано до 32Bit, Отладка & Режим деблокирования.

+1

Вы уверены, что VS9 берет '#pragma push' для учета шаблонов? – filmor

+1

@filmor Я не думаю, что шаблоны имеют к этому какое-то отношение. И без '#pragma pack' размер равен 16, а не 14 (поскольку компилятор должен гарантировать, что размер будет кратным 4). –

ответ

1

У меня нет решения, но по крайней мере часть причины для дополнительных байтов заключается в том, что тип не может иметь размер 0; даже пустая структура или класс (например, Alpha_data<false>) будет иметь размер 0-, размер которого не менее одного. С другой стороны, вы являются, выводя из них , поэтому оптимизация базового класса (что позволяет базовому классу иметь эффективный размер 0, даже если sizeof сообщает больше). По-видимому, MSC применяет только к одной из баз, возможно, первой. В противном случае, вы получите размер 15.

, вероятно, не очень полезны для вас, но г ++ дает размеры 12 и 13, что соответствует применению оптимизации пустого базового класса ко всем основаниям.

Если кто не знает вариант, чтобы сделать MSC быть более агрессивным в применении оптимизации пустого базового класса, ваши варианты чтобы сообщить об этом как об ошибке в корпорацию Майкрософт, в надежде, что они будут всеобъемлющим (так как стандарт Безразлично 't требует, чтобы пустая оптимизация базового класса использовалась вообще) или переключиться на g ++.

+0

Делает смысл, спасибо. Похоже, что эта «ошибка» существует уже некоторое время (например, http://stackoverflow.com/questions/12701469/why-empty-base-class-optimization-is-not-working, http: // stackoverflow. com/questions/6119927/empty-base-optimization-msvc), поэтому, вероятно, не нужно сообщать об этом MS. Я уверен, что мы найдем другое (возможно, не шаблонное) решение. – Matz

+0

@Matz Вы можете сохранить шаблоны на уровне пользователя. (Может быть более удобным для клиентского кода писать 'typedef Pixel Pixel3D;', чем использовать другое имя для класса.) Просто не предоставляйте реализацию по умолчанию, а скорее специализации для каждый возможный экземпляр (созданный из какого-то скрипта). –

Смежные вопросы