【问题标题】:Why some types does not work with uniform initialization syntax?为什么某些类型不适用于统一初始化语法?
【发布时间】:2013-10-03 08:03:05
【问题描述】:

在将我的一些 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

【问题讨论】:

  • "我注意到统一初始化不是那么统一。" 你说得对,我不能同意更多。

标签: c++ c++11 uniform-initialization


【解决方案1】:

“统一初始化”是一个非标准术语,不幸的是,它在提案阶段用于推广初始化列表功能。

不,您不能在任何地方使用它。根据我的经验,最好将其限制为

  • 聚合(没有构造函数;C++98 已经允许这样做,但 C++11 扩展了支持)
  • 序列 (initializer_list)
  • return 按值表达式调用非显式构造函数

盲目地改变一切并且期望语义没有改变只是争论不休——做某事是因为它是新的和不同的,而不是因为它是合适的。

至于泛型编程,是的,很难正确支持跨越上述类别的情况。在http://isocpp.org 的留言板上发布具体的投诉,也许负责该语言的人会更加努力地恢复“统一初始化”应该改善而不是恶化的通用顺序:v)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-12
    • 2012-02-05
    • 2012-05-17
    • 1970-01-01
    • 2019-05-05
    • 2018-03-06
    • 1970-01-01
    • 2015-12-10
    相关资源
    最近更新 更多