简体   繁体   English

动态对象的统一初始化

[英]uniform initialization for dynamic objects

#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? 统一初始化不适用于动态对象,还是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: 它适用于g ++ 4.7.1,但如果foo从另一个类继承,则main 两行都无法编译:

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. 它用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: 根据我对标准的阅读,你在第一个例子中得到了aggregate initialization

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). 聚合是一个数组或类(第9节),没有用户提供的构造函数(12.1),非静态数据成员(9.2)没有大括号或相等的初始值,没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),没有虚函数(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. 当初始化程序列表初始化聚合时,如8.5.4中所述,初始化程序列表的元素将作为聚合成员的初始化程序,增加下标或成员顺序。

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. 因此,第二个例子都不会编译。

both lines in main fail to compile if foo inherits from another class 如果foo从另一个类继承,则main 两行都无法编译

Ah, uniform initialization works differently for aggregates and non-aggregates: 啊,统一初始化对聚合和非聚合的工作方式不同:

List-initialization of an object or reference of type T is defined as follows: 列表初始化对象或类型T的引用定义如下:

  • If T is an aggregate, aggregate initialization is performed 如果T是聚合,则执行聚合初始化
  • [...] [...]
  • Otherwise, if T is a class type, constructors are considered 否则,如果T是类类型,则考虑构造函数

An aggregate is [..] a class [...] with no base classes [...] and no virtual functions. 聚合是[..]一个没有基类[...]且没有虚函数的类[...]。

So I still have to write custom constructors in my case, since I need the subtype polymorphism here. 所以我仍然需要在我的情况下编写自定义构造函数,因为我需要这里的子类型多态性。

I do not have the final version in hand at the moment, but draft N3242, § 8.5.4 List-initialization explicitly states that list-initialization can be used as the initializer in a new expression. 我目前还没有最终版本,但草案N3242,§8.5.4 § 8.5.4 List-initialization明确指出列表初始化可以用作新表达式中的初始化程序。 It also provides the following example: 它还提供了以下示例:

new std::vector<std::string>{"once", "upon", "a", "time"}; // 4 string elements

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM