在将我的一些 C++98 代码更新为 C++11 时,我注意到统一初始化并不是那么统一。其中一些与不完整类型有关,例如void
,而另一些与 pod 有关。例如,对于普通可复制类型,当初始化涉及复制/移动构造函数时,统一初始化不适用于直接初始化或复制初始化。
例如
template<class T>
T foo() { return T("Hello World");}
foo<void>();
foo<std::string>();
--------
template<class T>
T foo() { return T{"Hello World"};}
foo<void>();
foo<std::string>();
第一部分编译时,后半部分失败error: compound literal of non-object type 'void'
struct pod { int x;int y;};
pod p{1,2}; //ok pod p(1,2) is error as usual
pod p2(p);
struct foo
{
foo(foo const& rhs) : p_(rhs.p_){}
pod p_;
};
--------
struct pod { int x;int y;};
pod p{1,2};
pod p2{p};
struct foo
{
foo(foo const& rhs) : p_{rhs.p_}{}
pod p_;
};
在这里,后半部分的复制构造也失败了error: cannot convert 'pod' to 'int' in initialization
。虽然我认为,这个pod
类在 c++11 中是一个普通类型(甚至可以是普通可复制类型),但除了原始类型外,问题仍然相同
笔记:
虽然以下工作,
struct conv
{
operator int()const { return 1;}
};
pod p{1,2};
pod p2{conv{}};
这不,
struct conv
{
operator pod()const { return pod{1,2};}
};
pod p{1,2};
pod p2{conv{}};
我还注意到 C 数组确实适用于统一初始化,但不适用于复制/移动构造函数。但这可能是由于数组是一个没有复制/移动构造函数或赋值的聚合。虽然我不知道为什么在 c++11 中不允许使用这些语法(特别是当它们是类成员时,隐式复制/移动就是这样做的)。
那么,为什么我不能盲目地将所有 C++98 初始化更改为 C++11 样式的统一初始化(嗯,除了具有初始化列表的类型!)?
我正在使用 GCC 4.8.1