如何在派生 class 中可移植地初始化继承的模板化 POD 结构?
How to initialize inherited templated POD struct in derived class portably?
当我尝试在 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 上编译并显示“'{':缺少函数头(旧式正式列表?)”。
此时我不知道如何以符合标准的方式编写它。
谢谢。
这使您的最后一个示例有效:
std::cout << "Constructed " << this->a << std::endl;
演示:http://coliru.stacked-crooked.com/a/fe9715a447ffbea1
起初我无法在 MSVC++ 2015 (update 1) 下编译它。安装 update 3 后编译正常。
C++17 将以某种形式支持这一点:
Each direct public base, (since C++17) array element, or non-static class member, in order of array subscript/appearance in the class definition, is copy-initialized from the corresponding clause of the initializer list.
// 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;
}
当我尝试在 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 上编译并显示“'{':缺少函数头(旧式正式列表?)”。
此时我不知道如何以符合标准的方式编写它。
谢谢。
这使您的最后一个示例有效:
std::cout << "Constructed " << this->a << std::endl;
演示:http://coliru.stacked-crooked.com/a/fe9715a447ffbea1
起初我无法在 MSVC++ 2015 (update 1) 下编译它。安装 update 3 后编译正常。
C++17 将以某种形式支持这一点:
Each direct public base, (since C++17) array element, or non-static class member, in order of array subscript/appearance in the class definition, is copy-initialized from the corresponding clause of the initializer list.
// 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;
}