【问题标题】:How to initialize inherited templated POD struct in derived class portably?如何在派生类中可移植地初始化继承的模板化 POD 结构?
【发布时间】: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,参见 stackoverflow.com/questions/1120833/…

标签: c++ inheritance gcc visual-c++ portability


【解决方案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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 2019-10-01
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    相关资源
    最近更新 更多