有人可以帮我理解为什么以下代码无法编译(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;
}
Run Code Online (Sandbox Code Playgroud)
编译是:
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 };
^
Run Code Online (Sandbox Code Playgroud)
编辑:
感谢大家的回答,我现在理解了聚合初始化的概念.我错过了聚合不能拥有基类的事实.因此,我目前的实施计划需要改变.我想做的事情如下:
template < typename T >
struct base_class
{
int val_;
};
struct MyInt : public base_class<int>
{
void Func1() {}
};
struct MyDouble : public base_class<double>
{
void Func2() {}
};
Run Code Online (Sandbox Code Playgroud)
我将重做上面的代码,以避免使用子类来引入特殊的成员函数,同时避免代码重复.
放弃
以下是一粒盐,因为这是我对事物的解释.我绝不是专家.(另外我对聚合 - 初始化列表关系有一些疑问,我在这里说过.)
回答
据我所知,这是不可能的,因为v2的聚合初始化将应用于非聚合类类型B.
从这个答案可以看出,聚合必须没有基类,这使得B非聚合,因此不能通过大括号括起来的初始化列表进行初始化.
另一方面std::is_pod,由于POD定义在C++ 11中发生了变化,因此可能无法完成您的想法.因此,如果可以使用此类聚合初始值设定项初始化POD类型,则不会提示您.
加成
我主要在这里讨论聚合初始化,但更通用的术语是列表初始化,其限制较少.但是,检查我在链接资源中找到的所有情况都不可能进行列表初始化,因为(遵循资源的初始化列表的效果列表):
B 不是聚合B 不是专业化的 std::initializer_listB 没有
B 不是参考类型B无法进行复制初始化123而不是直接初始化,因为没有构造函数接受intB 未初始化值,因为初始化列表不是空的