#include <memory>
struct foo
{
std::unique_ptr<int> p;
};
int main()
{
foo bar { std::unique_ptr<int>(new int(42)) };
// okay
new foo { std::unique_ptr<int>(new int(42)) };
// error: no matching function for call to
// 'foo::foo(<brace-enclosed initializer list>)'
}
Does uniform initialization not work with dynamic objects, or is this a shortcoming of g++ 4.6.1?
It works with g++ 4.7.1, but both lines in main
fail to compile if foo
inherits from another class:
struct baz
{
// no data members, just some member functions
};
struct foo : baz
{
std::unique_ptr<int> p;
};
Again, shortcoming of my compiler? Or does uniform initialization not play well with inheritance?
It builds fine with g++-4.7. So presumably the latter. I'll have a look to see if I can find stronger evidence via the docs.
And in response to the inheritance addendum:
This simpler case also fails to compile:
struct baz
{
};
struct foo : baz
{
int b;
};
int main()
{
foo bar { 12 };
}
With:
testoo.cpp:14:18: error: no matching function for call to ‘foo::foo(<brace-enclosed initializer list>)’
testoo.cpp:14:18: note: candidates are:
testoo.cpp:7:8: note: foo::foo()
testoo.cpp:7:8: note: candidate expects 0 arguments, 1 provided
testoo.cpp:7:8: note: constexpr foo::foo(const foo&)
testoo.cpp:7:8: note: no known conversion for argument 1 from ‘int’ to ‘const foo&’
testoo.cpp:7:8: note: constexpr foo::foo(foo&&)
testoo.cpp:7:8: note: no known conversion for argument 1 from ‘int’ to ‘foo&&’
According to my reading of the standard, you have been getting aggregate initialization
in your first example:
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal- initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order.
Note that this explicitly forbids base classes. So to sum up - aggregate initialization is not allowed in the presence of base classes. And hence neither of the second examples will compile.