4

N3257 中,我找到了一个使用没有构造函数的初始化成员的示例,这很好。我想这是可能的,因为它是一个 POD。

template<typename T>
struct adaptor {
    NonStdContainer<T>* ptr;                // <- data member
    T* begin() { return ptr->getFirst(); }
    T* end() { return ptr->getLast() + 1; }
};
void f(NonStdContainer<int>& c) {
    for (auto i : adaptor<int>{&c})         // <- init
        { /* ... */ }
}

当我玩这个例子时,我用 a 替换*&,因为我不喜欢原始指针:

template<typename T>
struct adaptor {
    NonStdContainer<T>& ptr;                // <- data member, now REF
    T* begin() { return ptr->getFirst(); }
    T* end() { return ptr->getLast() + 1; }
};
void f(NonStdContainer<int>& c) {
    for (auto i : adaptor<int>{c})         // <- init
        { /* ... */ }
}

这很好,并且在没有警告的情况下使用 GCC-4.7.0 编译。

然后我对 POD 的初始化以及 C++0x 可能发生的变化感到好奇。在那里我找到了 Bjarnes FAQ。他在那里说 POD 可能包含指针,但没有引用

操作,现在我想知道:

  • 我这里是否有非 POD 对象,编译器无论如何都可以在没有构造函数的情况下对其进行初始化,而我只是想念这里使用了哪些机制?
  • 或者GCC-4.7.0 是否通过让我以这种方式初始化 ref 来表现非标准?
  • 还是自 Bjarnes FAQ 以来 std 发生了变化,也允许在 POD 中引用?

更新:我在当前 std ( 8.5.1 Aggregates [dcl.init.aggr] ) 中找到了聚合,但那里没有提到引用,所以我不确定它们与这个有什么关系

4

1 回答 1

4

引用标准 [dcl.init.aggr]:

聚合是一个数组或类(第 9 条),没有用户提供的构造函数(12.1),没有用于非静态数据成员的大括号或等号初始化程序(9.2),没有私有或受保护的非静态数据成员(第 11 条),没有基类(第 10 条),也没有虚函数(10.3)。

当聚合被初始化列表初始化时,如 8.5.4 中指定的,初始化列表的元素被视为聚合成员的初始化,按递增的下标或成员顺序。每个成员都从相应的初始化子句复制初始化......

这意味着您在这里有一个聚合,聚合可以按照您的方式进行初始化。POD 与它无关,它们实际上是用于与例如通信。C。

使用变量对引用进行复制初始化当然是合法的,因为这只是意味着

T& ref = c;

我这里是否有非 POD 对象,编译器无论如何都可以在没有构造函数的情况下对其进行初始化,而我只是想念这里使用了哪些机制?

是的,该对象是非 POD。

通过让我以这种方式初始化 ref,GCC-4.7.0 是否表现得非标准?

不。

于 2011-09-10T13:27:57.050 回答