C++0x Инициализация члена без конструктора

В N3257 я нашел пример использования инициализирующих элементов без конструктора, и это нормально. Я думаю, это возможно, потому что это POD.

template<typename T>
struct adaptor {
    NonStdContainer<T>* ptr;                // <- data member
    T* begin() { return ptr->getFirst(); }
    T* end() { return ptr->getLast() + 1; }
};
void f(NonStdContainer<int>& c) {
    for (auto i : adaptor<int>{&c})         // <- init
        { /* ... */ }
}

Когда я поиграл с этим примером, я заменил * с &потому что я не люблю сырые указатели:

template<typename T>
struct adaptor {
    NonStdContainer<T>& ptr;                // <- data member, now REF
    T* begin() { return ptr->getFirst(); }
    T* end() { return ptr->getLast() + 1; }
};
void f(NonStdContainer<int>& c) {
    for (auto i : adaptor<int>{c})         // <- init
        { /* ... */ }
}

Это было хорошо и скомпилировано без предупреждения с GCC-4.7.0.

Затем мне стало любопытно узнать об инициализации POD и о том, что могло бы измениться с C++0x. Там я нашел Bjarnes FAQ. Там он говорит, что POD могут содержать указатели, но без ссылок.

Опс, теперь мне интересно

  • Есть ли у меня не POD-объект, который компилятор может инициализировать без конструктора в любом случае, и я просто скучаю, какие механизмы используются здесь?
  • или GCC-4.7.0 ведет себя нестандартно, позволяя мне инициализировать ref таким образом?
  • или произошли изменения в std после Bjarnes FAQ, которые также позволяют ссылки в POD?

Обновление: я нашел агрегаты в текущем стандарте (8.5.1 Aggregates [dcl.init.aggr]), но ссылки там не упоминаются, поэтому я не уверен, как они связаны с этим

1 ответ

Решение

Цитируя стандарт [dcl.init.aggr]:

Агрегат - это массив или класс (раздел 9) без предоставленных пользователем конструкторов (12.1), без инициализаторов фигурных или равных скобок для нестатических элементов данных (9.2), без закрытых или защищенных нестатических элементов данных (Пункт 11), нет базовых классов (пункт 10) и нет виртуальных функций (10.3).

Когда агрегат инициализируется списком инициализаторов, как указано в 8.5.4, элементы списка инициализаторов берутся в качестве инициализаторов для элементов агрегата в возрастающем индексе или порядке элементов. Каждый член инициализируется копией из соответствующего предложения инициализатора...

Это означает, что у вас есть агрегат, агрегаты могут быть инициализированы так, как вы это делаете. POD не имеют к этому никакого отношения, они действительно предназначены для общения, например. C.

Инициализация копии ссылки с переменной, безусловно, допустима, потому что это просто означает

T& ref = c;

Есть ли у меня не POD-объект, который компилятор может инициализировать без конструктора в любом случае, и я просто скучаю, какие механизмы используются здесь?

Да, объект не POD.

GCC-4.7.0 ведет себя нестандартно, позволяя мне инициализировать ref таким образом?

Нет.

Другие вопросы по тегам