如何在派生类中可移植地初始化继承的模板化 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<A>
没有任何字段“base”。所以我尝试了以下更改。
template <typename A>
derived<A>::derived() : base<A> 1
std::cout << "Constructed " << a << std::endl;
GCC 现在将base<A>
识别为derived<A>
的字段,但声明a
未在此范围内声明。
有趣的是,此更改现在无法在 MSVC 上编译,并指出“'': missing function header (old-style form list?)”。
此时我不知道如何以符合标准的方式编写此代码。
谢谢。
【问题讨论】:
它在我的 VS15 上编译...... ...但不是他的最后一个示例,这仅在 VS15 中将: base<A>
替换为 : base
时有效。
我说的是base<A>
的最后一个例子。 (VS15 更新 3)
@ZivS 嗯,这很奇怪。 MVSC15 是否无法为我以外的其他人编译base<A>
版本?
重新使用 this->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 结构?的主要内容,如果未能解决你的问题,请参考以下文章