Полагаю, это не элегантное и удобное решение, но должно работать также с C ++ 11 и выдавать ошибку времени компиляции (не времени компоновки).
Идея состоит в том, чтобы добавить в Ваш struct дополнительный член, в последней позиции, типа без инициализации по умолчанию (и который не может инициализироваться значением типа VariablePtr
(или любым другим типом предшествующих значений)
К примеру
struct bar
{
bar () = delete;
template <typename T>
bar (T const &) = delete;
bar (int)
{ }
};
struct foo
{
char a;
char b;
char c;
bar sentinel;
};
Таким образом, вы вынуждены добавить все элементы в ваш список инициализации агрегата, включая значение для явной инициализации последнего значения (целое число для sentinel
, в примере), или вы получите "вызов" в удаленный конструктор ошибки 'bar'.
Итак
foo f1 {'a', 'b', 'c', 1};
компилируется, а
foo f2 {'a', 'b'}; // ERROR
нет.
К сожалению, также
foo f3 {'a', 'b', 'c'}; // ERROR
не компилируется.
- РЕДАКТИРОВАТЬ -
Как указано MSalters (спасибо), есть дефект (еще один дефект ) в моем исходном примере: значение bar
можно инициализировать значением char
(то есть преобразовать с int
), поэтому работает следующая инициализация
foo f4 {'a', 'b', 'c', 'd'};
, и это может сильно сбить с толку.
Чтобы избежать этой проблемы, я добавил следующий удаленный конструктор шаблонов
template <typename T>
bar (T const &) = delete;
, поэтому предыдущее объявление f4
дает ошибку компиляции, так как значение d
перехватывается удаляемым конструктором шаблона