gpt4 book ai didi

c++ - std::is_pod 与子类化

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:29:56 26 4
gpt4 key购买 nike

有人可以帮我理解为什么以下代码无法编译 (g++ 4.8)。我的理解是可以初始化一个 POD

#include <iostream>
#include <type_traits>

struct my_int
{
int val_;
};
struct B : public my_int
{
};

int main()
{
std::cout << std::is_pod<my_int>::value << std::endl;
std::cout << std::is_pod<B>::value << std::endl;
const my_int v = { 123 };
//const B v2 = { 123 }; // does not compile with g++ 4.8.

return 0;
}

编译是:

g++ -std=c++11 t.cxx
t.cxx: In function 'int main()':
t.cxx:24:21: error: could not convert '{123}' from '<brace-enclosed initializer list>' to 'const B'
const B v = { 123 };
^

编辑:

感谢大家的回答,我现在明白了聚合初始化的概念。我错过了聚合不能有基类的事实。因此我目前的实现计划需要改变。我想做类似的事情:

template < typename T >
struct base_class
{
int val_;
};
struct MyInt : public base_class<int>
{
void Func1() {}
};
struct MyDouble : public base_class<double>
{
void Func2() {}
};

我会重写上面的代码,避免使用子类引入特殊的成员函数,同时避免代码重复。

最佳答案

免责声明

请对以下内容持保留态度,因为这是我对事物的解释。我绝不是专家。 (我也对我在这里陈述的聚合 - 初始化列表关系有一些疑问。)

回答

据我所知这是不可能的,因为 v2 的聚合初始化将应用于非聚合类类型 B。

从这里answer你可以认为聚合不能有基类,这使得 B 成为非聚合,因此不能通过大括号括起来的初始化列表进行初始化。

另一方面,std::is_pod 可能不会按照您的想法去做,因为 POD 定义在 C++11 中发生了变化。因此,它不会提示您 POD 类型是否可以使用这样的聚合初始化器进行初始化。

添加

我在这里主要讨论聚合初始化,但更通用的术语是 list initialization限制较少。但是,检查我在链接资源中发现的所有情况,也无法进行列表初始化因为(在资源的初始化列表效果列表之后):

  • 初始化列表不为空
  • B 不是聚合
  • B 不是 std::initializer_list
  • 的特化
  • B 没有
    • 采用初始化列表的构造函数
    • 拟合列表签名的构造函数
  • B 不是引用类型
  • B 不能从 123 复制初始化,也不能直接初始化,因为没有采用 int 的构造函数
  • B 没有值初始化,因为初始化列表不为空

关于c++ - std::is_pod 与子类化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18922026/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com