Only aggregates may be initialized with an initializer list. Per 8.5.1:1, the inclusion of a user-provided constructor prevents a struct or class from being an aggregate:
c++11
8.5.1 Aggregates [dcl.init.aggr]
1 - An aggregate is an array or a class (Clause 9) with no user-provided constructors [...]
In C++03,
c++03
8.5.1 - Aggregates [dcl.init.aggr]
1 - An aggregate is an array or a class (clause class) with no user-declared constructors [...]
Aggregates are distinct from PODs (c++11 9:10); not all aggregates are POD and not all PODs are aggregates; a class with a user-provided destructor could be an aggregate but not a POD, while a class with a non-copy non-default constructor could be POD but not an aggregate.
Demonstration:
#include <type_traits>
#include <iostream>
struct non_pod_aggregate { int i, j; ~non_pod_aggregate() {} };
struct non_aggregate_pod { int i, j; non_aggregate_pod(int) {}
non_aggregate_pod() = default; };
int main() {
std::cout << std::is_pod<non_pod_aggregate>::value << '\n'; // false
std::cout << std::is_pod<non_aggregate_pod>::value << '\n'; // true
non_pod_aggregate{0, 0};
// non_aggregate_pod{0, 0}; // does not compile
}
In C++03, all PODs (c++03 9:4) are aggregates, but it is still possible to have aggregates that are not PODs; as above, a user-provided destructor is enough to disqualify a struct from being POD.