M.M M.M - 3 years ago 219
C++ Question

Value-initialization of class containing std::queue

Here is a MCVE:

#include <queue>

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

int main()
S s{};

With gcc 6.x
-std=c++14 -pedantic
I get warnings

<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 ^

In gcc 7.x, or clang , there are no warnings.

My question is: Is this code actually correct or not; and if it is correct, what are the warnings trying to warn me about exactly?

Answer Source

This is, in fact, ill-formed under the standard as published, which depicts queue with an explicit default constructor.

S is an aggregate; S s{}; is aggregate initialization and doesn't call the default constructor of S. Instead, since no explicit initializer is specified for q, it's copy-initialized from an empty initializer list, which is ill-formed because copy-list-initialization selected an explicit constructor.

GCC 7 gave queue a non-explicit default constructor (which is how it should be anyway), which is why you aren't seeing the error. Similarly, the default constructor of libc++'s queue has always been non-explicit.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download