#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>)'
}
统一初始化不适用于动态对象,还是g ++ 4.6.1的缺点?
它适用于g ++ 4.7.1,但如果main
继承自另一个类,则foo
中的两行都无法编译:
struct baz
{
// no data members, just some member functions
};
struct foo : baz
{
std::unique_ptr<int> p;
};
再次,我的编译器的缺点?或者统一初始化不能很好地继承?
答案 0 :(得分:4)
用g ++ - 4.7构建得很好。所以可能是后者。我将来看看是否可以通过文档找到更有力的证据。
并回应继承附录:
这个更简单的案例也无法编译:
struct baz
{
};
struct foo : baz
{
int b;
};
int main()
{
foo bar { 12 };
}
使用:
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&&’
根据我对该标准的解读,您在第一个例子中得到了aggregate initialization
:
聚合是一个没有用户提供的数组或类(第9条) 构造函数(12.1),非静态的支撑或相等初始化器 数据成员(9.2),没有私有或受保护的非静态数据成员 (第11条),没有基类(第10条),也没有虚函数 (10.3)。
按指定的初始化列表初始化聚合时 在8.5.4中,初始化列表的元素被视为 增加下标的聚合成员的初始化程序 或会员订单。
请注意,这明确禁止基类。总而言之 - 在基类存在的情况下不允许聚合初始化。因此,第二个例子都不会编译。
答案 1 :(得分:2)
如果
main
继承自另一个类,则foo
中的两行都无法编译
啊,统一初始化对聚合和非聚合的工作方式不同:
对象或类型T的引用的列表初始化定义如下:
- 如果T是聚合,则执行聚合初始化
- [...]
- 否则,如果T是类类型,则构造函数被视为
聚合是[..]一个没有基类[...]且没有虚函数的类[...]。
所以我仍然需要编写自定义构造函数,因为我需要这里的子类型多态。
答案 2 :(得分:1)
我目前还没有最终版本,但草案N3242 § 8.5.4 List-initialization
明确指出列表初始化可以用作新表达式中的初始化程序。它还提供了以下示例:
new std::vector<std::string>{"once", "upon", "a", "time"}; // 4 string elements