如何在派生类中可移植地初始化继承的模板化 POD 结构?

Posted

技术标签:

【中文标题】如何在派生类中可移植地初始化继承的模板化 POD 结构?【英文标题】:How to initialize inherited templated POD struct in derived class portably? 【发布时间】:2017-03-02 21:40:14 【问题描述】:

当我尝试在 GCC 上编译我的程序时遇到了一个问题,我很想知道如何使用 C++11 的初始化语法 e.g. struct int a; int b my_struct 1, 2 可移植地初始化继承的 POD 结构。下面的代码可以在 MSVC 上正常编译。

#include <iostream>

template <typename A>
struct base 
 A a;
;

template <typename A>
class derived : public base<A> 
public:
  derived();
;

template <typename A>
derived<A>::derived() : base 1 

  std::cout << "Constructed " << a << std::endl;


int main() 
  derived<int> d1;

但是,启用了 C++14 的 GCC 大致表明 derived&lt;A&gt; 没有任何字段“base”。所以我尝试了以下更改。

template <typename A>
derived<A>::derived() : base<A> 1 

  std::cout << "Constructed " << a << std::endl;

GCC 现在将base&lt;A&gt; 识别为derived&lt;A&gt; 的字段,但声明a 未在此范围内声明。

有趣的是,此更改现在无法在 MSVC 上编译,并指出“'': missing function header (old-style form list?)”。

此时我不知道如何以符合标准的方式编写此代码。

谢谢。

【问题讨论】:

它在我的 VS15 上编译...... ...但不是他的最后一个示例,这仅在 VS15 中将 : base&lt;A&gt; 替换为 : base 时有效。 我说的是base&lt;A&gt; 的最后一个例子。 (VS15 更新 3) @ZivS 嗯,这很奇怪。 MVSC15 是否无法为我以外的其他人编译base&lt;A&gt; 版本? 重新使用 this-&gt;a 与仅使用 a,参见 ***.com/questions/1120833/…。 【参考方案1】:

这使您的最后一个示例有效:

std::cout << "Constructed " << this->a << std::endl;

演示:http://coliru.stacked-crooked.com/a/fe9715a447ffbea1

起初我无法在 MSVC++ 2015(更新 1)下编译它。安装update 3 后编译正常。

【讨论】:

为什么这-> 在 GCC 上是必需的?无论如何,便携性问题仍然存在。 您似乎找到了一个几乎不受任何编译器支持的边缘情况。 刚刚检查...我仍在更新 1。我现在将安装更新 3 以检查是否是这个原因。【参考方案2】:

C++17 将以某种形式支持这一点:

表格aggregate_initialization:

每个直接公共基类、(C++17 起)数组元素或非静态类成员,按照类定义中数组下标/外观的顺序,从初始化器列表的相应子句复制初始化。

// aggregate
struct base1  int b1, b2 = 42; ;
// non-aggregate
struct base2 
  base2() : b3(42) 
  int b3;
;
// aggregate in C++17
struct derived : base1, base2  int d; ;
derived d1 1, 2,  , 4; // d1.b1 = 1, d1.b2 = 2,  d1.b3 = 42, d1.d = 4
derived d2     ,  , 4; // d2.b1 = 0, d2.b2 = 42, d2.b3 = 42, d2.d = 4

同时一个标准的方法是:

template <typename A>
    derived<A>::derived()  
        this->a = 1;

【讨论】:

以上是关于如何在派生类中可移植地初始化继承的模板化 POD 结构?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 7 中可移植地获取文件存储的块大小?

c++继承总结

如何在 C++ 中可移植地计算 sha1 哈希?

c++继承是如何工作的?

绑定与非绑定方法 继承 继承与抽象 查找属性关系 派生与覆盖 访问父类的内容

我可以防止非 POD 类中数组数据成员中元素的零初始化吗?