为什么在初始化列表中初始化POD数据时必须进行C样式的类型转换?

iam*_*ind 5 c++ constructor pod initializer-list language-lawyer

struct POD { int i, j; };    
class A {
  POD m_pod;
public:
  A() : m_pod({1,2}) {} // error
  A() : m_pod(static_cast<POD>({1,2})) {} // error
  A() : m_pod((POD) {1,2}) {} // ok!
};
Run Code Online (Sandbox Code Playgroud)

我在编译的旧生产代码中看到了这一点g++34,直到那时我才知道这个功能.
它是g ++特有的功能吗?如果没有那么,为什么需要进行类型转换,而且只允许进行C风格的转换?

Naw*_*waz 6

实际上C++ Standard(C++ 03和C++ 11)都不允许使用以下语法:

A() : m_pod((POD) {1,2}) {} // ok!
Run Code Online (Sandbox Code Playgroud)

由于GCC编译了这个,它是GCC扩展.

如果使用-pedanticoption 编译它,它会发出以下警告:

pod.cpp:8:29:警告:ISO C++禁止复合文字


在C++ 11中,您可以这样写:

A() : m_pod{1,2} {}
Run Code Online (Sandbox Code Playgroud)

演示:http://ideone.com/XaO4y

或者只是这个:

class A {
  POD m_pod {1,2}; //in-place initialization
public:
  A() {}
};
Run Code Online (Sandbox Code Playgroud)

虽然Ideone不支持这一点.


Mic*_*zek 5

您使用的语法不仅用于初始化列表,还用于声明之外的类类型的任何初始化。例如:

POD p;
p = (POD) {1, 2};
Run Code Online (Sandbox Code Playgroud)

这些被称为复合文字;它们在 C99 中被添加到 C 中。它们实际上在 C++ 中不受支持;GCC 允许它们在 C++(和 C89)中作为扩展。C++11增加了语法

p = POD({1, 2});
Run Code Online (Sandbox Code Playgroud)

或者在你的情况下:

A() : m_pod(POD({1,2})) {}
Run Code Online (Sandbox Code Playgroud)