Размер элемента объединения С++ на основе другого размера элемента
Рассмотрим следующий фрагмент кода:
struct S
{
union
{
int arr1[10];
char arr2[sizeof(arr1)];
};
};
Он успешно компилируется с gcc 4.9.2 в режиме С++ 03 и С++ 11. Однако, когда я изменяю S
как шаблон следующим образом:
template <size_t N>
struct S
{
union
{
int arr1[N];
char arr2[sizeof(arr1)];
};
};
Я получаю следующий вывод ошибки:
error: int S<10ul>::<anonymous union>::arr1 [10]’ is inaccessible
int arr1[N];
error: within this context
char arr2[sizeof(arr1)];
Clang компилирует обе версии только в режиме С++ 11. Мне любопытно, что здесь правильное поведение. Может быть, я должен явно указать, что размер arr2
sizeof(int) * N
?
Ответы
Ответ 1
Ваш союз анонимен. Таким образом, компилятор создаст arr1
и arr2
на уровне класса.
Из-за этого char arr2[sizeof(arr1)];
не будет правильно относиться к arr1
.
Вот обходной путь:
template <size_t N>
struct S
{
union A
{
int arr1[N];
char arr2[sizeof(arr1)];
};
};
Скомпилируется здесь: https://ideone.com/JcvOYg
Называя объединение, мы запрещаем компилятору включать его напрямую. Затем он может правильно восстановить arr1
.
Но это также означает, что arr1
и arr2
больше не являются членами S
.
Наконец, Members can be defined in terms of other members
, но последний должен быть "найден" компилятором.
Ответ 2
Вы можете сделать это:
template <size_t N>
class S
{
private:
union
{
int arr1[N];
char arr2[N*sizeof(int)];
};
};