Инициализация значений класса, содержащего std:: queue

Вот MCVE:

#include <queue>

struct S
{
    std::queue<int> q;
    int r;
};

int main()
{
    S s{};
}

С gcc 6.x -std=c++14 -pedantic Я получаю предупреждения

<source>:11:9: warning: converting to 'std::queue<int>' from initializer list would use explicit constructor 'std::queue<_Tp, _Sequence>::queue(_Sequence&&) [with _Tp = int; _Sequence = std::deque<int, std::allocator<int> >]'
 S s{};
     ^
<source>:11:9: note: in C++11 and above a default constructor can be explicit            ^

В gcc 7.x или clang нет предупреждений.

Мой вопрос: действительно ли этот код правильный или нет; и если это правильно, какие предупреждения пытаются точно предупредить меня?

Ответ 1

Это, по сути, плохо сформировалось в соответствии с опубликованным стандартом, в котором изображен queue с явным конструктором по умолчанию.

S - совокупность; S s{}; является агрегатной инициализацией и не вызывает конструктор по умолчанию S. Вместо этого, поскольку для q не указан явный инициализатор, он копируется с инициализацией из пустого списка инициализаторов, который плохо сформирован, потому что инициализация списка копий выбрала явный конструктор.

GCC 7 дал queue неявный конструктор по умолчанию (как и должно быть, так или иначе), поэтому вы не видите ошибку. Аналогично, конструктор по умолчанию libС++ queue всегда был неявным.